Um eine bessere mapcat zu verstehen, habe ich ein Beispiel:mapcat mit Karte und concat
user> (mapcat #(list % %) [1 2 3])
(1 1 2 2 3 3)
und versuchte zu reproduzieren, was der Doc mit beschreibt, absichtlich, Karte und concat:
user> (doc mapcat)
clojure.core/mapcat
([f & colls])
Returns the result of applying concat to the result of applying map
to f and colls. Thus function f should return a collection.
Damit verfolgt:
user> (concat (map #(list % %) [1 2 3]))
((1 1) (2 2) (3 3))
Wie Sie jedoch sehen können, funktioniert es nicht. Ich kann jedoch wie diese reduzieren verwenden, wissen aber nicht, ob es richtig ist:
user> (reduce #(concat %1 %2) (map #(vec (list % %)) [1 2 3]))
(1 1 2 2 3 3)
Die oben genannten Arbeiten, aber ich weiß nicht, ob es eine richtige Art und Weise ist neu zu erstellen, mit Karte und concat, was mapcat tut.
Grundsätzlich würde ich gerne von mapcat funktioniert unter der Haube.
Was passiert und wie kann ich auf die Quelle mapcat zugreifen? (Ich verwende Emacs + nrepl)
Die Verwendung von 'apply 'ist wahrscheinlich besser als' Reduzieren 'hier, weil' reduce 'ein' concat' für jedes Argumentpaar ausführt.Da "concat" faul ist, wenn die Werte tatsächlich erzwungen werden, könnten Sie mit einem _really_ deep-Aufruf-Stack enden, was möglicherweise zu einem Stack-Überlauf führt. [Hier ist ein einfaches Beispiel.] (Https://www.refheap.com/paste/6409) – DaoWen
Nur ein Tipp - in Ihrer Implementierung mit "reduzieren", ist es nicht notwendig, "concat" in einer anonymen Funktion zu wickeln. Dies funktioniert auch: '(reduziere concat (map ...))' und ist vorzuziehen, da es den Fall einer leeren Eingabe besser behandelt. – Alex