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 함수의 오버로드를 작성하는 것입니다. 코드 생성기가 도움이 될 것입니다.
나는 그것이 반복적이지 않고 가능하다고 믿지 않는다. 한 가지 간단한 이유는 요청하는 함수의 반환 유형을 정의 할 수 없다는 것입니다.
예를 들어 입력이 List (List (1,2), List (3,4)) 인 경우 반환 유형은 List [Tuple2 [Int]]가됩니다. 세 개의 요소가있는 경우 반환 유형은 List [Tuple3 [Int]] 등이됩니다.
List [AnyRef] 또는 List [Product]를 반환 한 다음 각 조건에 대해 하나씩 여러 케이스를 만들 수 있습니다.
일반 목록 전치의 경우 다음과 같이 작동합니다.
def transpose[T](l: List[List[T]]): List[List[T]] = l match {
case Nil => Nil
case Nil :: _ => Nil
case _ => (l map (_.head)) :: transpose(l map (_.tail))
}
적용 가능한 scalaz / cats / (여기에 가장 좋아하는 기능적 라이브러리 삽입) 경로를 따르고 싶지 않다면, (_, _)
구문이 중첩에 약간 어색 하긴하지만 패턴 매칭을 사용하는 것이 좋습니다. 변경해 보겠습니다.
import scala.{Tuple2 => &}
for (i1 & i2 & i3 & i4 <- list1 zip list2 zip list3 zip list4) yield (i1, i2, i3, i4)
는 &
여기에 임의의 선택을해야 좋은 중위 보이는 것도있다. 하지만 코드 검토 중에 몇 가지 눈썹을 올릴 수 있습니다.
또한 어떤 작업을해야 할 수 있습니다 zip
(예를 Future
들)
product-collections has aflatZip
operation up to arity 22.
scala> List(1,2,3) flatZip Seq("a","b","c") flatZip Vector(1.0,2.0,3.0) flatZip Seq(9,8,7)
res1: com.github.marklister.collections.immutable.CollSeq4[Int,String,Double,Int] =
CollSeq((1,a,1.0,9),
(2,b,2.0,8),
(3,c,3.0,7))
With Scalaz:
import scalaz.Zip
import scalaz.std.list._
// Zip 3
Zip[List].ap.tuple3(List("a1", "b1"),
List("a2", "b2"),
List("a3", "b3"))
// Zip 4
Zip[List].ap.tuple4(List("a1", "b1"),
List("a2", "b2"),
List("a3", "b3"),
List("a4", "b4"))
// Zip 5
Zip[List].ap.tuple5(List("a1", "b1"),
List("a2", "b2"),
List("a3", "b3"),
List("a4", "b4"),
List("a5", "b5"))
For more than 5:
// Zip 6
Zip[List].ap.apply6(List("a1", "b1"),
List("a2", "b2"),
List("a3", "b3"),
List("a4", "b4"),
List("a5", "b5"),
List("a6", "b6"))((_, _, _, _, _, _))
// Zip 7
Zip[List].ap.apply7(List("a1", "b1"),
List("a2", "b2"),
List("a3", "b3"),
List("a4", "b4"),
List("a5", "b5"),
List("a6", "b6"),
List("a7", "b7"))((_, _, _, _, _, _, _))
...
// Zip 12
Zip[List].ap.apply12(List("a1", "b1"),
List("a2", "b2"),
List("a3", "b3"),
List("a4", "b4"),
List("a5", "b5"),
List("a6", "b6"),
List("a7", "b7"),
List("a8", "b8"),
List("a9", "b9"),
List("a10", "b10"),
List("a11", "b11"),
List("a12", "b12"))((_, _, _, _, _, _, _, _, _, _, _, _))
참고URL : https://stackoverflow.com/questions/1664439/can-i-zip-more-than-two-lists-together-in-scala
'developer tip' 카테고리의 다른 글
UILabel 글꼴 크기? (0) | 2020.09.15 |
---|---|
`react-native run-ios`가 오류를 반환합니다 : iPhone X 시뮬레이터를 찾을 수 없음 (0) | 2020.09.15 |
글꼴 크기 변경 단축키 (0) | 2020.09.15 |
C # : 개체 목록을 해당 개체의 단일 속성 목록으로 변환하는 방법은 무엇입니까? (0) | 2020.09.14 |
Sphinx의 autodoc을 사용하여 클래스의 __init __ (self) 메서드를 문서화하는 방법은 무엇입니까? (0) | 2020.09.14 |