in beiden Fällen nicht den Wert von y
verändern können:
in ersten Fall for
Wieder stellt die y
auf jeder Schleife Schritt, das ist, warum Sie nicht, dass es Wert ändern könnte, auch wenn es wandelbar war .
der zweite Fall zeigt, dass der Wert wirklich unveränderbar ist, geben Sie (inc y)
auf jedem Schritt, aber y
ist immer Null. Einfaches Beispiel:
(let [x 10]
(inc x)
x)
;;=> 10
In der Regel diese Art von Aufgabe kann in der Regel mit den folgenden Ansätzen gelöst werden:
Erstens ist die einfache Rekursion:
(defn count-rec [data]
(if (seq data)
(inc (count-rec (rest data)))
0))
user> (count-rec [1 2 3 4 5])
;;=> 5
es in einer Weise fehlerhaft ist, da es nicht Schwanz rekursiv ist und für große Sammlungen fehlschlagen würde
Der zweite ist clojure loop
:
(defn count-loop [data]
(loop [res 0 data data]
(if (seq data)
(recur (inc res) (rest data))
res)))
user> (count-loop [1 2 3 4 5])
;;=> 5
auch können Sie explizite Endrekursion verwenden, die sehr ähnlich sein würde:
(defn count-tailrec
([data] (count-tailrec 0 data))
([c data] (if (seq data)
(recur (inc c) (rest data))
c)))
user> (count-tailrec [1 2 3 4 5])
;;=> 5
Der dritte würde verwenden, um die reduce
Funktion:
(defn count-reduce [data]
(reduce (fn [res _] (inc res)) 0 data))
user> (count-reduce [1 2 3 4 5])
;;=> 5
Just for fun Sie auch diese verwenden könnte Art und Weise (ich würde es nicht raten, da es ein Overkill im Vergleich zu reduce
ist):
(defn count-map [data]
(apply + (map (constantly 1) data)))
user> (count-map [1 2 3 4 5])
;;=> 5
Sie könnten auch clojure des wandelbaren Primitive verwenden, aber es ist nicht idiomatischen und sollte so lange vermieden werden, wie es sein könnte:
(defn count-atom [data]
(let [c (atom 0)]
(run! (fn [_] (swap! c inc)) data)
@c))
user> (count-atom [1 2 3 4 5])
;;=> 5
und hier kommt den Cheat
[SPOILER ALARM!]
4clojure blockiert die Verwendung von count
Funktion in dieser Aufgabe, aber nicht blockiert die .size
Methode der Sammlungen des Java, so dass es mit #(.size (seq %))
gelöst werden kann
Eine Sache zu beachten, wie Sie clojure lernen, ist, dass 'for' kein Looping-Konstrukt ist - es ist ein Listenverständnis, um Listen zu erstellen.Wenn Sie also eine Schleife erstellen möchten, ist es normalerweise am besten, 'loop' zu verwenden. Rückblickend auf dieses habe ich 'reduce' verwendet, was neben der reinen Rekursion die" funktionalste Programmierung "ist, um das Problem anzugehen (mehr als eine explizite Schleife, meine ich). Prost und viel Spaß! – Josh