【问题标题】:Merge two LinkedHashMap in Scala在 Scala 中合并两个 LinkedHashMap
【发布时间】:2018-05-18 21:04:04
【问题描述】:

有这个代码

def mergeWith[K, X, Y, Z](xs: mutable.LinkedHashMap[K, X], ys: mutable.LinkedHashMap[K, Y])(f: (X, Y) => Z): mutable.LinkedHashMap[K, Z] =
  xs.flatMap {
    case (k, x) => ys.get(k).map(k -> f(x, _))
  }

它给了我这个:

val map1 = LinkedHashMap(4 -> (4), 7 -> (4,7))
val map2 = LinkedHashMap(3 -> (3), 6 -> (3,6), 7 -> (3,7))

val merged = mergeWith(map1,map2){ (x, y) => (x, y) }
merged: scala.collection.mutable.LinkedHashMap[Int,(Any, Any)] = Map(7 -> ((4,7),(3,7)))

但我想要的是这个:

merged: scala.collection.mutable.LinkedHashMap[Int,(Any, Any)] = Map(3 -> (3), 4 -> (4), 6 -> (3,6), 7 -> ((4,7),(3,7)))

如何修改我的代码来获取它?

【问题讨论】:

    标签: scala dictionary merge linkedhashmap


    【解决方案1】:

    当前的mergeWith() 签名无法做到这一点。特别是,您正在尝试创建 LinkedHashMap[K,Z] 但没有 Z 输入。获得Z 的唯一方法是调用f(),这需要XY 作为传递参数。

    所以如果xsLinkedHashMap[Int,Char] 类型并且具有元素(2 -> 'w'),并且ys 是类型LinkedHashMap[Int,Long] 并且具有元素(8 -> 4L),那么你将如何调用f(c:Char, l:Long) 以便你有一个[K,Z] 两个键 28 的条目?不可能。

    如果mergeWith() 签名可以简化,您可以这样做。

    def mergeWith[K,V](xs: collection.mutable.LinkedHashMap[K, V]
                      ,ys: collection.mutable.LinkedHashMap[K, V]
                      )(f: (V, V) => V): collection.mutable.LinkedHashMap[K,V] = {
      val ns = collection.mutable.LinkedHashMap[K,V]()
      (xs.keySet ++ ys.keySet).foreach{ k =>
        if (!xs.isDefinedAt(k)) ns.update(k, ys(k))
        else if (!ys.isDefinedAt(k)) ns.update(k, xs(k))
        else ns.update(k, f(xs(k), ys(k)))
      }
      ns
    }
    

    这会为您给出的示例产生所需的结果,但它具有许多不良品质,其中最重要的是可变数据结构。

    顺便说一句,没有Tuple1 这样的东西,所以(4)4 是一样的。每当您看到输入 Any 时,这都是一个很好的迹象,表明您的设计需要重新思考。

    【讨论】:

      猜你喜欢
      • 2018-12-31
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 2016-03-27
      • 2018-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多