假设我有以下元组列表:
val tuples = listOfStrings.map(string => {
val split = string.split(":")
(split(0), split(1), split(2))
})
我想在列表中得到split(0),在另一个列表中得到split(1),依此类推。 一个简单的方法是通过写:
list1 = tuples.map(x => x._1).toList
list2 = tuples.map(x => x._2).toList
list3 = tuples.map(x => x._3).toList
在没有编写3个单独的陈述的情况下,是否有更优雅(功能)的方法来实现上述目标?
答案 0 :(得分:12)
这会将您的结果作为列表列表:
tuples.map{t => List(t._1, t._2, t._3)}.transpose
如果要将它们存储在局部变量中,只需执行:
val List(l1,l2,l3) = tuples.map{t => List(t._1, t._2, t._3)}.transpose
更新:正如Blaisorblade指出的那样,标准库实际上有一个内置的方法:unzip3
,就像unzip
一样,但是对于三元组而不是对:
val (l1, l2, l3) = tuples.unzip3
毋庸置疑,你应该赞成这种方法而不是上面的手动解决方案(但是对于arity> 3的元组,这仍然适用)。
答案 1 :(得分:10)
你想要解压缩:
scala> val (numbers, homonyms) = List(("one", "won"), ("two", "too")).unzip
numbers: List[java.lang.String] = List(one, two)
homonyms: List[java.lang.String] = List(won, too)
答案 2 :(得分:3)
如果你想要一些可以用于任意元组大小的东西:
val tupleSize = 3
0.until(tupleSize).toList
.map(x => (_:Product).productElement(x).asInstanceOf[String])
.map(tuples.map(_))
显然,如果你有一个数组列表,这可以更优雅地表达。
答案 3 :(得分:1)
您可以在一行中编写语句。
像
(list1, list2, list3) = tuples.foldRight((List[String](), List[String](), List[String]()))( (a,b) => (a._1 :: b._1, a._2 :: b._2, a._3 :: b._3 ) )
答案 4 :(得分:0)
我不知道优雅,但你可以在一行中完成它而不需要存储元组的中间步骤。也许这有点难以理解......
(for(split <- listOfStrings.map(_.split(":")))
yield List(split(0), split(1), split(2))).transpose
repl example:
scala> listOfStrings
res1: List[java.lang.String] = List(a:b:c, d:e:f, g:h:i)
scala> (for(split <- listOfStrings.map(_.split(":")))
| yield List(split(0), split(1), split(2))).transpose
res2: List[List[java.lang.String]] = List(List(a, d, g), List(b, e, h), List(c, f, i))