In Clojure möchte ich zwei Listen kombinieren, um eine Liste von Paaren zu erhalten.
> (zip '(1 2 3) '(4 5 6))
((1 4) (2 5) (3 6))
In Haskell oder Ruby heißt die Funktion zip . Die Implementierung ist nicht schwierig, aber ich wollte sicherstellen, dass mir keine Funktion in Core oder Contrib entgeht.
Es ist ein Zip - Namespace in Kern, aber es wird beschrieben , wie der Zugang zum Zipper funktionalen Technik, die scheint nicht zu sein , was ich bin nach.
Gibt es eine äquivalente Funktion zum Kombinieren von zwei oder mehr Listen auf diese Weise in Core?
Wenn dies nicht der Fall ist, liegt es daran, dass es einen idiomatischen Ansatz gibt, der die Funktion unnötig macht?
zip
Funktion in der Tupelo-Bibliothek: cloojure.github.io/doc/tupelo/tupelo.core.html#var-zipAntworten:
macht was du willst:
Haskell braucht eine Sammlung von
zipWith
(zipWith3
,zipWith4
, ...) Funktionen, weil sie alle der Notwendigkeit einer spezifisch sein Typ ; Insbesondere muss die Anzahl der von ihnen akzeptierten Eingabelisten festgelegt werden. (Diezip
,zip2
,zip3
, ... Familie kann als Spezialisierung der angesehen werdenzipWith
Familie zur gemeinsamen Nutzung Fall fache Vervielfachung).Im Gegensatz dazu unterstützen Clojure und andere Lisps Funktionen mit variabler Arität gut.
map
ist einer von ihnen und kann auf ähnliche Weise wie bei Haskell zum "Tupeln" verwendet werdenDie idiomatische Methode zum Erstellen eines "Tupels" in Clojure besteht darin, einen kurzen Vektor zu erstellen, wie oben dargestellt.
(Der Vollständigkeit halber ist zu beachten, dass Haskell mit einigen grundlegenden Erweiterungen variable Aritätsfunktionen zulässt. Die Verwendung dieser Funktionen erfordert jedoch ein gutes Sprachverständnis, und die Vanille Haskell 98 unterstützt sie wahrscheinlich überhaupt nicht. Daher sind feste Aritätsfunktionen vorzuziehen für die Standardbibliothek.)
quelle
zip
wenn die Sammlungen nicht dieselbe Länge haben. Ruby setzt die Verarbeitung fort und liefertnil
s für die kürzere Sammlung, während Clojure die Verarbeitung beendet, sobald eine der Sammlungen erschöpft ist.zip
verhält es sichmap
in dieser Hinsicht wie Clojure .oder allgemeiner
quelle
quelle
Um Ihnen genau das zu geben, was Sie wollten, erhalten Sie durch Zuordnen
list
zwischen den beiden Listen eine Liste mit Listen wie in Ihrem Beispiel. Ich denke, dass viele Clojurianer dazu neigen würden, Vektoren dafür zu verwenden, obwohl es mit allem funktionieren wird. und die Eingänge müssen nicht vom gleichen Typ sein. map erstellt daraus seqs und ordnet dann die seqs zu, sodass jede seq'able-Eingabe einwandfrei funktioniert.quelle
Der eingebaute Weg wäre einfach die Funktion 'Interleave':
quelle
(partition 2 (interleave [1 2 3 4][5 6 7 8]))
Es gibt eine Funktion namens zipmap, die einen ähnlichen Effekt haben kann (zipmap
(1 2 3)
(4 5 6)). Die Ausgabe lautet wie folgt: {3 6, 2 5, 1 4}quelle
# (Kartenliste% anwenden) transponiert eine Matrix genau wie die Python zip * -Funktion. Als Makrodefinition:
user => (defmacro py-zip [lst] `(Kartenliste anwenden ~ lst))
# 'user / py-zip
Benutzer => (py-zip '((1 2 3 4) (9 9 9 9) (5 6 7 8)))
((1 9 5) (2 9 6) (3 9 7) (4 9 8))
Benutzer => (py-zip '((1 9 5) (2 9 6) (3 9 7) (4 9 8))
((1 2 3 4) (9 9 9 9) (5 6 7 8))
quelle