Frage

Ich versuche, eine „Verringerung der Karte“ -Funktion zu implementieren. Das heißt, es sollte eine Sequenz zurück, bestehend aus dem Ergebnis der f zu den ersten 2 Artikel von coll Anwendung, gefolgt von dem Ergebnis der f zu diesem Ergebnis und dem dritten Element in coll Anwendung, etc.

(def c [[0 0 0 0] [1 0 0 0] [0 1 0 0] [0 0 1 0] [0 0 0 1]])

(defn- sum-vector [v1 v2]
  (map + v1 v2))

(defn reduce-map [f coll & acc]
  (if (< (count coll) 2)
    (if (empty? acc) coll acc)
    (let [head (apply f (take 2 coll))
          tail (drop 2 coll)]
      (recur f (conj tail head) (conj acc head)))))

Zum Beispiel, Aufruf dieser Funktion wie folgt aus:

(reduce-map sum-vector c)

zurückkehren sollte:

[[1 0 0 0] [1 1 0 0] [1 1 1 0] [1 1 1 1]]

(Eigentlich sollte es wahrscheinlich kehrt das erste Element als auch unverändert, besser zu imitieren map, aber ich kann das in Ordnung bringen später.)

So, jetzt, das ist, was es gibt:

((1 1 1 1) (1 1 1 0) (1 1 0 0) (1 0 0 0))

Wie kann ich "Push" am Ende eines (ny) f?

Wenn ich Ersatz reduce-map für recur, das ist, was es gibt:

(((1 1 1 1) ((1 1 1 0) ((1 1 0 0) ((1 0 0 0))))))

Was ist der Unterschied zwischen recur und wahrer Rekursion in meinem obigen Code?

Und gibt es eine eingebaute, oder besser, oder mehr idiomatisch, Art und Weise der Umsetzung reduce-map?

Schließlich möchte ich die Ausgangssequenz, faul sein. Muss ich wickeln nur die ganze Sache in lazy-seq?

War es hilfreich?

Lösung

Das klingt ein wenig wie reductions .

Was am Ende des seq „Schieben“: im Allgemeinen ASTA kein „Ende“ hat, vgl (iterate inc 0).

In Bezug auf „Schieben“ am Ende einer Liste: Listen werden für das nicht ausgelegt ist. Verwenden Sie einen Vektor. Seed Ihren Akku mit [], nicht nil.

In Bezug auf lazy-seq: Verwenden Sie "true" Rekursion statt recur. Hier ein Beispiel:

(defn integer-seq
  [start]
  (lazy-seq
    (cons start (integer-seq (inc start)))))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top