使用4(或N)个集合一次只能产生一个值(1xN)(即为tuple4 +压缩)

fra*_*cca 6 collections scala tuples for-comprehension

scala> val a = List(1,2)
a: List[Int] = List(1, 2)

scala> val b = List(3,4)
b: List[Int] = List(3, 4)

scala> val c = List(5,6)
c: List[Int] = List(5, 6)

scala> val d = List(7,8)
d: List[Int] = List(7, 8)

scala> (a,b,c).zipped.toList
res6: List[(Int, Int, Int)] = List((1,3,5), (2,4,6))
Run Code Online (Sandbox Code Playgroud)

现在:

scala> (a,b,c,d).zipped.toList
<console>:12: error: value zipped is not a member of (List[Int], List[Int], List[Int],     List[Int])
              (a,b,c,d).zipped.toList
                       ^
Run Code Online (Sandbox Code Playgroud)

我在其他地方搜索过这个,包括这个这个,但没有确定的答案.

我想做以下或类似的事情:

for((itemA,itemB,itemC,itemD) <- (something)) yield itemA + itemB + itemC + itemD
Run Code Online (Sandbox Code Playgroud)

有什么建议?

Lui*_*hys 3

简短回答:

for (List(w,x,y,z) <- List(a,b,c,d).transpose) yield (w,x,y,z)
  // List[(Int, Int, Int, Int)] = List((1,3,5,7), (2,4,6,8))
Run Code Online (Sandbox Code Playgroud)

为什么你希望它们作为元组,我不确定,但一个更有趣的情况是当你的列表具有不同类型时,例如,你想将它们组合成一个对象列表:

case class Person(name: String, age: Int, height: Double, weight: Double)
val names =   List("Alf", "Betty")
val ages =    List(22, 33)
val heights = List(111.1, 122.2)
val weights = List(70.1, 80.2)
val persons: List[Person] = ???
Run Code Online (Sandbox Code Playgroud)

解决方案1:使用transpose,如上所述:

for { List(name: String, age: Int, height: Double, weight: Double) <- 
        List(names, ages, heights, weights).transpose
    } yield Person(name, age, height, weight)
Run Code Online (Sandbox Code Playgroud)

在这里,我们需要列表提取器中的类型注释,因为transpose给出了一个List[List[Any]].

解决方案2:使用迭代器:

val namesIt   = names.iterator
val agesIt    = ages.iterator
val heightsIt = heights.iterator
val weightsIt = weights.iterator

for { name <- names } 
  yield Person(namesIt.next, agesIt.next, heightsIt.next, weightsIt.next)
Run Code Online (Sandbox Code Playgroud)

有些人会避免使用迭代器,因为它们涉及可变状态,因此不是“功能性的”。但如果您来自 Java 世界,它们很容易理解,并且如果您实际拥有的已经是迭代器(输入流等),它们可能会适合。