2017-08-05 2 views
3

Ich wollte einen Clojure-Vektor in einem Atom, um einen statusbehafteten FIFO zu modellieren (Push bis zum Ende, Pop von Anfang an).Clojure Atome konvertieren Vektoren in Listen?

versucht
(def stack (atom [])) 

dann push wie folgt:

(swap! stack #(conj % 1)) 
(swap! stack #(conj % 2)) 

[1 2] 

erwarten aber

(2 1) 

Keine große Sache bekommen, es bedeutet nur, dass ich umkehren müssen (O (n)) der Wert von das Atom (persistente Liste), um die Elemente in der Reihenfolge zu erhalten, als ich sie geschoben habe (z. B. einen Strom von imperativen Befehlen an eine virtuelle Maschine der Reihe nach). Trotzdem war es eine Überraschung.

Gibt es einen clojure.core FIFO, den ich in ein Atom packen kann? Ich dachte an priority-map, aber es scheint übertrieben. Die Beispiele für swap! auf clojuredocs.org verwenden Listen oder Karten, nicht ganz was ich wollte. Ich habe viele Beispiele gefunden, indem ich "FIFO Clojure" gegoogelt habe, aber einige sind ein bisschen reich, z. B. clojure.core.cache (kartenartig und nicht vektorartig); Ringpuffer von amalloy (externe Abhängigkeit). Auf der Suche nach etwas wirklich Kleinem und Einfachem. Ich habe in den automatischen Vorschlägen von StackOverflow keine Antwort gefunden.

Antwort

5

Etwas stimmt im weiteren Kontext Ihres Codes nicht ganz. Ich gehe davon aus, dass Sie viel mehr tun als in dem von Ihnen geposteten Beispiel?

Hier ist das Ergebnis in meinem REPL und was ich erwarten würde:

user=> (def stack (atom [])) 
#'user/stack 
user=> (swap! stack #(conj % 1)) 
[1] 
user=> (swap! stack #(conj % 2)) 
[1 2] 
user=> @stack 
[1 2] 

Wenn Vektoren verwendet wird, werden Elemente an das Ende der Sammlung hinzugefügt. Das Ergebnis, das Sie sehen, sieht aus wie das Verhalten, das Sie erhalten würden, wenn stack stattdessen eine Liste wäre, z. nach vorne und füge hinzu:

user=> (def stack (atom '())) 
#'user/stack 
user=> (swap! stack #(conj % 1)) 
(1) 
user=> (swap! stack #(conj % 2)) 
(2 1) 
user=> @stack 
(2 1) 

Also ich frage mich, wenn irgendwo im Code, haben Sie irgendwie eine Liste am Ende definieren, sondern als ein Vektor.

+0

Sie haben Recht. Untersuchung. –

+0

Der Kontext war eine Reihe von wiederholten Tests von Pushing und Popping. Sieht so aus, als wenn ich das letzte Element von einem Vektorstapel lösche, bleibt dem Atom eine leere Liste und kein leerer Vektor übrig. Nachfolgende Pushs conj auf die Liste und nicht ein Vektor. Die Behebung ist einfach in meiner Pop-Funktion --- zurück in einen leeren Vektor, wenn der letzte Pop den Stapel leert. –

+1

Nein, '(pop [1])' ist '[]'. Das ist nicht dein Problem. Wenn Sie "Rest" oder "Seq" nennen, könnte das eine Liste ergeben. – amalloy

Verwandte Themen