在scala中将两个列表一起排序

时间:2012-08-02 11:40:34

标签: list scala functional-programming

说我有两个清单:

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 个答案:

答案 0 :(得分:5)

根据您的修改,for - 理解:

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

按需运作。

答案 1 :(得分:4)

解决方案非常简单:

first groupBy(_._1) toList

结果:

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

first是你的第一个清单(第二个目的是什么)?

答案 2 :(得分: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}

答案 3 :(得分:-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

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