【问题标题】:scala: type equality of two variablesscala:两个变量的类型相等
【发布时间】:2015-06-24 03:33:23
【问题描述】:

我有两个Map[String, T]s,其中TFruit 子类型的一个实例。我需要从两个 Map 构建新 Map,其中键是两个映射的公共键名,值是 Seq[Fruit] 如果两个映射的值共享相同的类型。

class Fruit

case class Apple() extends Fruit
case class Banana(num: Int) extends Fruit
case class Orange() extends Fruit

例如,如果我有以下两张地图:

val map1 = Map("first" -> Apple(),
               "second" -> Banana(3),
               "third" -> Orange())

val map2 = Map("first" -> Orange(),
               "second" -> Banana(4),
               "third" -> Orange())

我需要结果图,map3,它有以下成员:

generateMap(map1: Map[String, Fruit], map2: Map[String, Fruit]): Map[String, Seq[Fruit]]

=> results a map look like

    Map("second" -> Seq(Banana(3), Banana(4)),
        "third"  -> Seq(Orange(), Orange())

我不确定如何编写函数,generateMap。有人可以帮我实现吗? (使用 Scala 2.11.x)

请注意,类定义(Fruits 和其他)是固定的,因此我无法修改它们。

【问题讨论】:

    标签: scala reflection types equality


    【解决方案1】:
    scala> val r: Map[String, Seq[Fruit]] = (map1.toList ++ map2.toList).
       groupBy(x => x._1).
       mapValues(lst => lst.map(x => x._2)).
       .filter { 
         case (key, lst) => lst.forall(x =>
                 x.getClass == lst.head.getClass)
       }
    
    r: Map[String, Seq[Fruit]] = Map(third -> List(Orange(), Orange()), 
        second -> List(Banana(3), Banana(4)))
    

    【讨论】:

    • 谢谢,但结果与我的预期不同。因为 map1("first") 与 map2("first") 的类型不同,所以生成的输出不应该有 "first"。
    【解决方案2】:

    val m3 = (map1.toSeq ++ map2.toSeq). // Combine the maps
       groupBy (x=>x._1). //Group by the original keys
       map{case (k,lst)=> (k, lst.map(x=> x._2))}. //Strip the keys from the grouped sequences
       filter{case (_, lst) => lst.forall(i => lst.head.getClass == i.getClass)}. //Filter out hetergeneous seqs
        toMap // Make a map

    【讨论】:

      【解决方案3】:

      没有forall:

      (map1.toList ++ map2.toList).groupBy(_._1).mapValues(_.map(_._2))
        .filter(_._2.map(_.getClass).toSet.tail.isEmpty)
      
      Map(third -> List(Orange(), Orange()), second -> List(Banana(3), Banana(4)))
      

      forall 的版本相比,此版本需要更多(但在filter 内部仍然是线性的)CPU 和内存,因此您应该仅将它用于小型集合。

      【讨论】:

        猜你喜欢
        • 2012-07-12
        • 1970-01-01
        • 2017-01-20
        • 2015-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多