14

次のタプルのリストがあるとします。

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

リストで分割(0)、別のリストで分割(1)などを取得したいと思います。これを実現する簡単な方法は、次のように書くことです。

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

3つの別々のステートメントを書かずに上記を達成するためのよりエレガントな(機能的な)方法はありますか?

4

5 に答える 5

13

これにより、リストのリストとして結果が得られます。

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

UPDATE : Blaisorblade で指摘されているように、標準ライブラリには実際には this: の組み込みメソッドがありますunzip3が、これはunzipペアではなくトリプル用です:

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

言うまでもなく、上記の手動のソリューションよりもこの方法を優先する必要があります (ただし、アリティ > 3 のタプルの場合、これは引き続き適用されます)。

于 2012-09-12T16:42:20.647 に答える
3

任意のタプルサイズに使用できるものが必要な場合:

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

明らかに、代わりに配列のリストがあれば、これはよりエレガントに表現できます。

于 2012-09-12T17:01:32.120 に答える
1

ステートメントを 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 ) )
于 2012-09-12T16:32:19.973 に答える
0

エレガントについてはわかりませんが、タプルを格納する中間ステップなしで1行で実行できます。多分それは少し読みにくいです...

(for(split <- listOfStrings.map(_.split(":")))
  yield List(split(0), split(1), split(2))).transpose

replの例:

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))
于 2012-09-12T16:53:20.770 に答える