[scala] Scala에서 두 개 이상의 목록을 함께 압축 할 수 있습니까?

다음 스칼라 목록이 주어지면 :

val l = List(List("a1", "b1", "c1"), List("a2", "b2", "c2"), List("a3", "b3", "c3"))

어떻게 얻을 수 있습니까?

List(("a1", "a2", "a3"), ("b1", "b2", "b3"), ("c1", "c2", "c3"))

zip은 두 개의 목록을 결합하는 데만 사용할 수 있으므로 어떻게 든 기본 목록을 반복 / 축소해야한다고 생각합니다. 당연히 다음은 작동하지 않습니다.

scala> l reduceLeft ((a, b) => a zip b)
<console>:6: error: type mismatch;
 found   : List[(String, String)]
 required: List[String]
       l reduceLeft ((a, b) => a zip b)

이 작업을 수행하는 방법에 대한 제안이 있습니까? 나는 그것을하는 아주 간단한 방법을 놓치고 있다고 생각합니다.

업데이트 : 각각 M 요소가있는 N 목록 목록을 가져와 M TupleN 목록을 만들 수있는 솔루션을 찾고 있습니다.

업데이트 2 : 내 특정 사용 사례가 튜플 목록이 아닌 목록 목록을 갖는 것이 더 낫기 때문에 호박의 응답을 수락하고 있습니다. 또한 기본 방법을 사용하므로 가장 간단합니다.



답변

나는 임의의 크기의 튜플 목록을 생성하는 것이 가능하다고 생각하지 않지만, 대신 목록 목록을 가져 오는 것에 신경 쓰지 않는다면 전치 함수 가 필요한 것을 정확하게 수행합니다.


답변

scala> (List(1,2,3),List(4,5,6),List(7,8,9)).zipped.toList
res0: List[(Int, Int, Int)] = List((1,4,7), (2,5,8), (3,6,9))

향후 참조를 위해.


답변

따라서이 코드는 OP의 요구에 응답하지 않습니다. 이것은 4 년 된 스레드이기 때문일뿐만 아니라 제목 질문에 대한 답변을 제공하므로 누군가 유용하다고 생각할 수도 있습니다.

3 개의 컬렉션을 압축하려면 :

as zip bs zip cs map {
  case ((a,b), c) => (a,b,c)
}


답변

예, zip3 사용 .


답변

transpose트릭을 수행합니다. 가능한 알고리즘은 다음과 같습니다.

def combineLists[A](ss:List[A]*) = {
    val sa = ss.reverse;
    (sa.head.map(List(_)) /: sa.tail)(_.zip(_).map(p=>p._2 :: p._1))
}

예를 들면 :

combineLists(List(1, 2, 3), List(10,20), List(100, 200, 300))
// => List[List[Int]] = List(List(1, 10, 100), List(2, 20, 200))

대답은 입력에서 가장 짧은 목록의 크기로 잘립니다.

combineLists(List(1, 2, 3), List(10,20))
// => List[List[Int]] = List(List(1, 10), List(2, 20))


답변

모든 다른 클래스 등의 다른 튜플 크기의 스칼라 취급은 ( Tuple1, Tuple2, Tuple3, Tuple4, …, Tuple22그들은에서 모든 상속을 할 때) Product, 특성 실제로 튜플의 다른 크기의 데이터 값을 사용하려면 특성은 충분한 정보를 전달하지 않습니다 모두 같은 함수에 의해 반환 될 수 있다면. (그리고 스칼라의 제네릭은이 경우를 처리 할만큼 강력하지 않습니다.)

가장 좋은 방법은 22 개의 모든 튜플 크기에 대해 zip 함수의 오버로드를 작성하는 것입니다. 코드 생성기가 도움이 될 것입니다.


답변

적용 가능한 scalaz / cats / (여기에 좋아하는 기능적 라이브러리를 삽입하십시오) 경로를 따르고 싶지 않다면, (_, _)구문이 중첩에 약간 어색 하긴하지만 패턴 매칭을 사용하는 것이 좋습니다. 변경해 보겠습니다.

import scala.{Tuple2 => &}

for (i1 & i2 & i3 & i4 <- list1 zip list2 zip list3 zip list4) yield (i1, i2, i3, i4)

&여기에 임의의 선택을해야 좋은 중위 보이는 것도있다. 하지만 코드 검토 중에 몇 가지 눈썹을 올릴 수 있습니다.

또한 어떤 작업을해야 할 수 있습니다 zip(예를 Future들)