106 votes

Peut-on zipper plus de deux listes ensemble en Scala ?

Étant donné la liste Scala suivante :

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

Comment puis-je obtenir :

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

Étant donné que la fermeture éclair ne peut être utilisée que pour combiner deux listes, je pense que vous devez itérer/réduire la liste principale d'une manière ou d'une autre. Sans surprise, ce qui suit ne fonctionne pas :

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)

Avez-vous des suggestions sur la manière de procéder ? Je pense qu'il me manque un moyen très simple de le faire.

Mise à jour : Je cherche une solution qui puisse prendre une liste de N listes avec M éléments chacune et créer une liste de M TupleNs.

Mise à jour 2 : Il s'avère qu'il est préférable pour mon cas d'utilisation spécifique d'avoir une liste de listes, plutôt qu'une liste de tuples, donc j'accepte la réponse de Citrouille. C'est aussi la plus simple, puisqu'elle utilise une méthode native.

0 votes

Duplication possible de Zip de plusieurs séquences

0 votes

Cela vaut vraiment la peine d'être noté : stackoverflow.com/questions/1683312/

0 votes

@VenkatSudheerReddyAedama J'ai également posé la question, cinq jours plus tard. ;-)

232voto

Xorlev Points 4658
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))

Pour une référence future.

35 votes

C'est idéal pour la fermeture éclair de trois listes. Dommage que cela ne fonctionne pas pour plus de trois listes :(

2 votes

Notez que cela doit d'abord être dans un tuple : zipped n'est pas une fonction de List .

17 votes

zipped est déprécié dans Scala 2.13. En 2.13, faire l1.lazyZip(l2).lazyZip(l3).toList

38voto

copumpkin Points 1894

Je ne pense pas qu'il soit possible de générer une liste de tuples de taille arbitraire, mais la fonction fonction de transposition fait exactement ce dont vous avez besoin si cela ne vous dérange pas d'obtenir une liste de listes à la place.

0 votes

Merci, cela fonctionne parfaitement ! Au fur et à mesure que j'entre dans mon cas d'utilisation spécifique, je vois qu'une liste de listes serait meilleure de toute façon, car je dois mapper et réduire les différentes sous-listes.

2 votes

@JoshCason dans le sens le plus étroit de "plus de deux", bien sûr. Trois est en effet plus que deux. J'ai interprété la question dans le sens plus large de "plus de deux", c'est-à-dire un nombre arbitraire. Et dans ce cas, il n'est pas possible de faire ce que la question demande, à moins que vous n'atteigniez HList et autres.

0 votes

Le lien dans la réponse est cassé, le nouveau lien est scala-lang.org/api/2.12.1/scala/

35voto

Bijou Trouvaille Points 1067

Ce bout de code ne répondra donc pas aux besoins du PO, et pas seulement parce que ce fil de discussion date de quatre ans, mais il répond à la question du titre, et peut-être que quelqu'un le trouvera utile.

Pour zipper 3 collections :

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

1 votes

Pour faire 4 collections ressemble : as zip bs zip cs zip ds map { case ((a,b),c)} map {case ((a,b),c,d)=>(a,b,c,d)}

2 votes

@JamesTobin, tu raccourcis à as zip bs zip cs zip ds map {case (((a,b),c),d)=>(a,b,c,d) }

0 votes

Idéal pour les listes de différents types.

11voto

Harold L Points 3340

Oui, avec zip3 .

2 votes

Merci, mais cela ne fonctionne qu'avec 3 listes. Je cherche une solution qui puisse prendre une liste de N listes avec M éléments chacune et créer une liste de M TupleNs.

5voto

Ken Bloom Points 27197

Scala traite toutes ses tailles de tuple différentes comme des classes différentes ( Tuple1 , Tuple2 , Tuple3 , Tuple4 ,..., Tuple22 ) alors qu'ils héritent tous de la Product ce trait ne contient pas assez d'informations pour utiliser réellement les valeurs de données des différentes tailles de tuples si elles pouvaient toutes être retournées par la même fonction. (Et les génériques de Scala ne sont pas assez puissants pour gérer ce cas non plus).

Votre meilleure chance est d'écrire des surcharges de la fonction zip pour les 22 tailles de Tuple. Un générateur de code vous aiderait probablement à le faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X