2017-06-10 4 views
2

Ich bin häufig in der Lage, die mein Code wie so liest:Wie wiederhole ich bis zu einem festen Punkt in Clojure?

(iterate improve x) 

Und ich bin auf der Suche nach dem ersten Wert, der nicht mehr eine Verbesserung gegenüber dem vorherigen ist. Weder filter noch take-while eignen sich für eine offensichtliche Lösung. Ich bin jedoch zögerlich schreiben:

(loop [current x 
     next (improve x)] 
    (if (= current next) 
    current 
    (recur next (improve next)))) 

oder:

(let [improvements (iterate improve x)] 
    (->> (map vector improvements (rest improvements)) 
    (filter (partial apply =)) 
    (ffirst))) 

Denn irgendwann diese immer wiederholend und sicher Fixpunktiteration ist so eine grundlegende Aufgabe, dass es muss eine Art sein von der Bibliotheksunterstützung irgendwo, oder?

Antwort

7

Sie reduce und reduced verwenden können, wenn notwendig, zu stoppen. reduced umschließt das Argument in einem speziellen Objekt, das reduce entwickelt, um die Verarbeitung sofort nach dem Zurückgeben des umbrochenen Werts zu suchen und zu beenden.

(def vals (iterate improve x)) 

(reduce #(if (= %1 %2) (reduced %1) %2) vals) 
0

könnten Sie verwenden drop-while dann first:

(defn still-improving? [[x y]] 
    ...) 

(->> st 
    (iterate transition) 
    (partition 2 1) 
    (drop-while still-improving?) 
    ffirst) 
Verwandte Themen