Por ejemplo supongamos que tengoEn Scala, ¿es posible comprimir dos listas de diferentes tamaños?
val letters = ('a', 'b', 'c', 'd', 'e')
val numbers = (1, 2)
¿Es posible producir una lista
(('a',1), ('b',2), ('c',1),('d',2),('e',1))
Por ejemplo supongamos que tengoEn Scala, ¿es posible comprimir dos listas de diferentes tamaños?
val letters = ('a', 'b', 'c', 'd', 'e')
val numbers = (1, 2)
¿Es posible producir una lista
(('a',1), ('b',2), ('c',1),('d',2),('e',1))
Sus letras y números son tuplas, no listas. Así que vamos a arreglar eso
scala> val letters = List('a', 'b', 'c', 'd', 'e')
letters: List[Char] = List(a, b, c, d, e)
scala> val numbers = List(1,2)
numbers: List[Int] = List(1, 2)
Ahora bien, si comprímalos no obtenemos el resultado deseado
scala> letters zip numbers
res11: List[(Char, Int)] = List((a,1), (b,2))
Pero eso sugiere que si los números se repiten infinitamente entonces el problema se solucionaría
scala> letters zip (Stream continually numbers).flatten
res12: List[(Char, Int)] = List((a,1), (b,2), (c,1), (d,2), (e,1))
Desafortunadamente, eso se basa en el conocimiento de que los números son más cortos que las letras. Así que para arreglar todo para arriba
scala> ((Stream continually letters).flatten zip (Stream continually numbers).flatten take (letters.size max numbers.size)).toList
res13: List[(Char, Int)] = List((a,1), (b,2), (c,1), (d,2), (e,1))
La más corta de las listas debe repetirse indefinidamente. En este caso es obvio que numbers
es más corta, pero en caso de que necesite que funcione en general, aquí es cómo puede hacerlo:
def zipLongest[T](list1 : List[T], list2 : List[T]) : Seq[(T, T)] =
if (list1.size < list2.size)
Stream.continually(list1).flatten zip list2
else
list1 zip Stream.continually(list2).flatten
val letters = List('a', 'b', 'c', 'd', 'e')
val numbers = List(1, 2)
println(zipLongest(letters, numbers))
Usted podría hacer un simple chiste, utilizando el map
método
val letters = List('a', 'b', 'c', 'd', 'e')
val numbers = List(1, 2)
val longZip1 = letters.zipWithIndex.map(x => (x._1, numbers(x._2 % numbers.length)))
//or, using a for loop
//for (x <- letters.zipWithIndex) yield (x._1, numbers(x._2 % numbers.size))
Si no desea volver a utilizar cualquiera de los datos de lista sin embargo tendrá que saber lo que los huecos son para ser llenado con anticipación:
val result = (0 to (Math.max(list1.size, list2.size) - 1)) map { index =>
(list1.lift(index).getOrElse(valWhen1Empty),list2.lift(index).getOrElse(valWhen2Empty))
}
Dudo que esto va a funcionar bien con las listas o corrientes de curso infinitas ...