以下是将两个列表组合在一起的非常简单的请求:
scala> list1
res17: List[(Int, Double)] = List((1,0.1), (2,0.2), (3,0.3), (4,0.4))
scala> list2
res18: List[(Int, String)] = List((1,aaa), (2,bbb), (3,ccc), (4,ddd))
所需的输出如下:
((aaa,0.1),(bbb,0.2),(ccc,0.3),(ddd,0.4))
我试过了:
scala> (list1 ++ list2)
res23: List[(Int, Any)] = List((1,0.1), (2,0.2), (3,0.3), (4,0.4),
(1,aaa), (2,bbb), (3,ccc), (4,ddd))
可是:
scala> (list1 ++ list2).groupByKey
<console>:10: error: value groupByKey is not a member of List[(Int,
Any)](list1 ++ list2).groupByKey
任何提示?谢谢!
答案 0 :(得分:1)
您正在寻找的方法是groupBy
:
(list1 ++ list2).groupBy(_._1)
如果您知道每个键只有两个值,则可以加入它们:
scala> val pairs = List((1, "a1"), (2, "b1"), (1, "a2"), (2, "b2"))
pairs: List[(Int, String)] = List((1,a1), (2,b1), (1,a2), (2,b2))
scala> pairs.groupBy(_._1).values.map {
| case List((_, v1), (_, v2)) => (v1, v2)
| }
res0: Iterable[(String, String)] = List((b1,b2), (a1,a2))
如果两个列表包含相同顺序的相同键,则可以使用zip
的另一种方法:
scala> val l1 = List((1, "a1"), (2, "b1"))
l1: List[(Int, String)] = List((1,a1), (2,b1))
scala> val l2 = List((1, "a2"), (2, "b2"))
l2: List[(Int, String)] = List((1,a2), (2,b2))
scala> l1.zip(l2).map { case ((_, v1), (_, v2)) => (v1, v2) }
res1: List[(String, String)] = List((a1,a2), (b1,b2))
答案 1 :(得分:1)
这是一个快速的单行:
scala> list2.map(_._2) zip list1.map(_._2)
res0: List[(String, Double)] = List((aaa,0.1), (bbb,0.2), (ccc,0.3), (ddd,0.4))
如果您不确定为什么会这样,请继续阅读!我将逐步扩展它:
list2.map(<function>)
map
方法迭代list2
中的每个值并将您的函数应用于它。在这种情况下,list2
中的每个值都是一个Tuple2(一个具有两个值的元组)。你想要做的是访问第二个元组值。要访问第一个元组值,请使用._1
方法并使用._2
方法访问第二个元组值。这是一个例子:
val myTuple = (1.0, "hello") // A Tuple2
println(myTuple._1) // prints "1.0"
println(myTuple._2) // prints "hello"
所以我们想要的是一个函数文字,它接受一个参数(列表中的当前值)并返回第二个元组值(._2
)。我们可以像这样编写函数文字:
list2.map(item => item._2)
我们不需要为item
指定类型,因为编译器足够聪明,可以通过目标类型来推断它。一个非常有用的捷径是,我们可以完全省略item
并将其替换为单个下划线_
。所以它被简化(或者被解冻,取决于你如何看待它):
list2.map(_._2)
关于这一个班轮的另一个有趣的部分是zip
方法。所有zip
都需要两个列表并将它们组合成一个列表,就像你最喜欢的连帽衫上的拉链一样!
val a = List("a", "b", "c")
val b = List(1, 2, 3)
a zip b // returns ((a,1), (b,2), (c,3))
干杯!