Scala: How to convert tuple elements to lists

主宰稳场 提交于 2019-12-28 11:54:14

问题


Suppose I have the following list of tuples:

val tuples = listOfStrings.map(string => {
            val split = string.split(":")
            (split(0), split(1), split(2))
        })

I would like to get the split(0) in a list, split(1) in another list and so on. A simple way this could be achieved is by writing:

list1 = tuples.map(x => x._1).toList
list2 = tuples.map(x => x._2).toList
list3 = tuples.map(x => x._3).toList

Is there a more elegant (functional) way of achieving the above without writing 3 separate statements?


回答1:


This will give you your result as a list of list:

tuples.map{t => List(t._1, t._2, t._3)}.transpose

If you want to store them in local variables, just do:

val List(l1,l2,l3) = tuples.map{t => List(t._1, t._2, t._3)}.transpose

UPDATE: As pointed by Blaisorblade, the standard library actually has a built-in method for this: unzip3, which is just like unzip but for triples instead of pairs:

val (l1, l2, l3) = tuples.unzip3

Needless to say, you should favor this method over my hand-rolled solution above (but for tuples of arity > 3, this would still still apply).




回答2:


You want unzip:

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)



回答3:


If you want something that can be used for arbitrary tuple sizes:

val tupleSize = 3
0.until(tupleSize).toList
    .map(x => (_:Product).productElement(x).asInstanceOf[String])
    .map(tuples.map(_))

Obviously, this could be expressed more elegantly if you had a List of Arrays instead.




回答4:


You could just write the statements in a single line.

Like

 (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 ) )



回答5:


I don't know about elegant but you could do it in one line without the intermediate step of storing the tuples. Perhaps it's a little hard to read...

(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))


来源:https://stackoverflow.com/questions/12392409/scala-how-to-convert-tuple-elements-to-lists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!