4

假设我有两个列表:

List(("a",1),("b",4),("d",5),("a",7),("b",6)) 

List("a","b","c","d")

我想根据第一个列表对它们进行分组,这样我得到:

List("a" -> List(("a",1),("a",7)), "b" -> List(("b",4),("b",6)), "d" -> List(("d",5)))

实现这一目标的最佳方法是什么?我知道我可以对预先确定的值使用 groupBy 和模式匹配,但是当第二个列表不是预先确定的时,我会有点卡住。

编辑:

我需要第二个列表中对象的副本作为已处理列表的键。我可能需要按第二个列表中的 on 对象的参数进行分组,但仍将整个对象保持为键……如果有意义的话。

List(("a",1),("b",4),("d",5),("a",7),("b",6)) 
List(("a",1,1),("b",2,3),("c",5,6),("d",6,7))

变成:

 List(("a",1,1) -> List(("a",1),("a",7)), ("b",2,3) -> List(("b",4),("b",6)), ("d",6,7) -> List(("d",5)))

对不起,不清楚!

4

4 回答 4

5

根据您的编辑,使用for-comprehension:

for {
  key <- second
  pair <- first.groupBy(_._1).get(key)
} yield key -> pair

或未加糖的等价物:

second.flatMap(key => first.groupBy(_._1).get(key).map(key -> _))

这两者都groupBy对每个键执行操作。如果这是一个问题,您当然可以使用稍微详细一点的方法来避免它:

val mappings = first.groupBy(_._1)
second.flatMap(key => mappings.get(key).map(key -> _))

并解决您的新编辑问题:如果您需要转换第二个列表中的每个项目以将其用作第一个列表的键,您可以通过几种方法来解决这个问题。例如,给定:

val first = List(("a", 1), ("b", 4), ("d", 5), ("a", 7), ("b", 6))
val second = List(("a", 1, 1), ("b", 2, 3), ("c", 5, 6), ("d", 6, 7))

任何一个:

for {
  item @ (key, _, _) <- second
  pair <- first.groupBy(_._1).get(key)
} yield item -> pair

或者:

for {
  item <- second
  pair <- first.groupBy(_._1).get(item._1)
} yield item -> pair

根据需要工作。

于 2012-08-02T11:52:20.363 回答
4

解决方案非常简单:

first groupBy(_._1) toList

结果:

List((a,List((a,1), (a,7))), (d,List((d,5))), (b,List((b,4), (b,6))))

你的第一个列表在哪里first(第二个的目的是什么)?

于 2012-08-02T11:43:14.047 回答
1

其他方式。

val first = List(("a",1),("b",4),("d",5),("a",7),("b",6))
val second = List(("a",1,1),("b",2,3),("c",5,6),("d",6,7))
first groupBy {k => second find {_._1 == k._1} get}
于 2012-08-02T12:32:12.917 回答
-1
val a = List(("a",1),("b",4),("d",5),("a",7),("b",6))
val b = List(("a",1,1),("b",2,3),("c",5,6),("d",6,7))
val a1 = a.groupBy{ _._1 }
b.flatMap{ x => a1.get(x._1).map{x -> _} }

或者

val a = List(("a",1),("b",4),("d",5),("a",7),("b",6))
val b = List(("a",1,1),("b",2,3),("c",5,6),("d",6,7))
b.view.map{ x => x -> a.filter{ _._1 == x._1 } }.filter{ _._2.nonEmpty }.toList

第二种方法应该是最有效的。

于 2012-08-02T15:05:41.123 回答