Suche…


Syntax

  • '()()
  • '(1 2 3 4 5)(1 2 3 4 5)
  • '(1 foo 2 bar 3)(1 'foo 2 'bar 3)
  • ( list 1 2 3 4 5)(1 2 3 4 5)
  • ( list* [1 2 3 4 5])(1 2 3 4 5)
  • [][]
  • [1 2 3 4 5][1 2 3 4 5]
  • ( vector 1 2 3 4 5)[1 2 3 4 5]
  • ( vec '(1 2 3 4 5))[1 2 3 4 5]
  • {} => {}
  • {:keyA 1 :keyB 2}{:keyA 1 :keyB 2}
  • {:keyA 1, :keyB 2}{:keyA 1 :keyB 2}
  • ( hash-map :keyA 1 :keyB 2){:keyA 1 :keyB 2}
  • ( sorted-map 5 "five" 1 "one"){1 "one" 5 "five"} (Einträge werden nach Schlüssel sortiert, wenn sie als Sequenz verwendet werden)
  • #{}#{}
  • #{1 2 3 4 5}#{4 3 2 5 1} (ungeordnet)
  • ( hash-set 1 2 3 4 5)#{2 5 4 1 3} (ungeordnet)
  • ( sorted-set 2 5 4 3 1)#{1 2 3 4 5}

Sammlungen

Alle integrierten Clojure-Kollektionen sind unveränderlich und heterogen, haben wörtliche Syntax und unterstützen die Funktionen conj , count und seq .

  • conj gibt eine neue Sammlung zurück, die einer vorhandenen Sammlung mit einem hinzugefügten Element entspricht, entweder in "konstanter" oder logarithmischer Zeit. Was genau das bedeutet, hängt von der Sammlung ab.
  • count gibt die Anzahl der Elemente in einer Sammlung in konstanter Zeit zurück.
  • seq gibt für eine leere Sammlung oder eine Folge von Elementen für eine nicht leere Sammlung in konstanter Zeit nil zurück.

Listen

Eine Liste ist in Klammern angegeben:

()
;;=> ()

Eine Clojure-Liste ist eine einzeln verknüpfte Liste . conj "verbindet" ein neues Element mit der effizientesten Stelle der Sammlung. Bei Listen ist dies am Anfang:

(conj () :foo)
;;=> (:foo)

(conj (conj () :bar) :foo)
;;=> (:foo :bar)

Im Gegensatz zu anderen Sammlungen werden nicht leere Listen bei der Auswertung als Aufrufe von speziellen Formularen, Makros oder Funktionen ausgewertet. Während also (:foo) die wörtliche Darstellung der Liste enthalten :foo als einziges Element, Bewertung (:foo) in einem REPL bewirkt eine IllegalArgumentException geworfen werden , weil ein Schlüsselwort nicht als aufgerufen werden kann nullary Funktion .

(:foo)
;; java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :foo

Um zu verhindern, dass Clojure eine nicht leere Liste auswertet, können Sie diese quote :

'(:foo)
;;=> (:foo)

'(:foo :bar)
;;=> (:foo :bar)

Leider werden die Elemente nicht ausgewertet:

(+ 1 1)
;;=> 2

'(1 (+ 1 1) 3)
;;=> (1 (+ 1 1) 3)

Aus diesem Grund sollten Sie in der Regel verwenden list , eine variadische Funktion , die alle ihre Argumente und verwendet diese Ergebnisse zu konstruieren , um eine Liste auswertet:

(list)
;;=> ()

(list :foo)
;;=> (:foo)

(list :foo :bar)
;;=> (:foo :bar)

(list 1 (+ 1 1) 3)
;;=> (1 2 3)

count gibt die Anzahl der Elemente in konstanter Zeit zurück:

(count ())
;;=> 0

(count (conj () :foo))
;;=> 1

(count '(:foo :bar))
;;=> 2

Sie können anhand der list? testen, ob etwas eine list? Prädikat:

(list? ())
;;=> true

(list? '(:foo :bar))
;;=> true

(list? nil)
;;=> false

(list? 42)
;;=> false

(list? :foo)
;;=> false

Sie können das erste Element einer Liste mit peek :

(peek ())
;;=> nil

(peek '(:foo))
;;=> :foo

(peek '(:foo :bar))
;;=> :foo

Sie können mit pop eine neue Liste ohne das erste Element erhalten:

(pop '(:foo))
;;=> ()

(pop '(:foo :bar))
;;=> (:bar)

Beachten Sie , wenn Sie versuchen, pop eine leere Liste, erhalten Sie eine bekommen IllegalStateException :

(pop ())
;; java.lang.IllegalStateException: Can't pop empty list

Schließlich sind alle Listen Sequenzen. Sie können also alles mit einer Liste machen, die Sie mit jeder anderen Sequenz tun können. Mit Ausnahme der leeren Liste gibt der Aufruf von seq in einer Liste genau dasselbe Objekt zurück:

(seq ())
;;=> nil

(seq '(:foo))
;;=> (:foo)

(seq '(:foo :bar))
;;=> (:foo :bar)

(let [x '(:foo :bar)]
  (identical? x (seq x)))
;;=> true

Sequenzen

Eine Sequenz ähnelt einer Liste: Es ist ein unveränderliches Objekt, das Ihnen in konstanter Zeit sein first Element oder den rest seiner Elemente geben kann. Sie können auch cons truct eine neue Sequenz aus einer bestehenden Sequenz und ein Element am Anfang zu bleiben.

Sie können mit dem seq? testen, ob etwas eine Sequenz ist seq? Prädikat:

(seq? nil)
;;=> false

(seq? 42)
;;=> false

(seq? :foo)
;;=> false

Wie Sie bereits wissen, sind Listen Sequenzen:

(seq? ())
;;=> true

(seq? '(:foo :bar))
;;=> true

Alles, was Sie erhalten, wenn Sie seq oder rseq oder keys oder vals einer nicht leeren Sammlung aufrufen, ist ebenfalls eine Sequenz:

(seq? (seq ()))
;;=> false

(seq? (seq '(:foo :bar)))
;;=> true

(seq? (seq []))
;;=> false

(seq? (seq [:foo :bar]))
;;=> true

(seq? (rseq []))
;;=> false

(seq? (rseq [:foo :bar]))
;;=> true

(seq? (seq {}))
;;=> false

(seq? (seq {:foo :bar :baz :qux}))
;;=> true

(seq? (keys {}))
;;=> false

(seq? (keys {:foo :bar :baz :qux}))
;;=> true

(seq? (vals {}))
;;=> false

(seq? (vals {:foo :bar :baz :qux}))
;;=> true

(seq? (seq #{}))
;;=> false

(seq? (seq #{:foo :bar}))
;;=> true

Denken Sie daran, dass alle Listen Sequenzen sind, aber nicht alle Sequenzen Listen sind. Während Listen peek und pop und count in konstanter Zeit unterstützen, muss eine Sequenz im Allgemeinen keine dieser Funktionen unterstützen. Wenn Sie versuchen, peek oder pop in einer Sequenz aufzurufen, die nicht auch die Stack-Schnittstelle von Clojure unterstützt, erhalten Sie eine ClassCastException :

(peek (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack

(pop (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack

(peek (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack

(pop (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack

(peek (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack

(pop (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack

Wenn Sie rufen Sie count auf eine Sequenz, die nicht implementieren count in konstanter Zeit, werden Sie nicht einen Fehler; Stattdessen durchquert Clojure die gesamte Sequenz bis zum Ende und gibt dann die Anzahl der Elemente zurück, die es durchlaufen hat. Dies bedeutet, dass die count für allgemeine Sequenzen linear und nicht konstant ist. Sie können testen , ob etwas konstante Zeit unterstützt count mit dem counted? Prädikat:

(counted? '(:foo :bar))
;;=> true

(counted? (seq '(:foo :bar)))
;;=> true

(counted? [:foo :bar])
;;=> true

(counted? (seq [:foo :bar]))
;;=> true

(counted? {:foo :bar :baz :qux})
;;=> true

(counted? (seq {:foo :bar :baz :qux}))
;;=> true

(counted? #{:foo :bar})
;;=> true

(counted? (seq #{:foo :bar}))
;;=> false

Wie oben erwähnt, können Sie first das erste Element einer Sequenz abrufen. Beachten Sie, dass first seq zu ihrem Argument aufrufen wird, sodass es für alle "seqable" -Ergebnisse verwendet werden kann, nicht nur für tatsächliche Sequenzen:

(first nil)
;;=> nil

(first '(:foo))
;;=> :foo

(first '(:foo :bar))
;;=> :foo

(first [:foo])
;;=> :foo

(first [:foo :bar])
;;=> :foo

(first {:foo :bar})
;;=> [:foo :bar]

(first #{:foo})
;;=> :foo

Wie oben erwähnt, können Sie rest , um eine Sequenz zu erhalten, die alle Elemente außer einer der ersten Elemente einer vorhandenen Sequenz enthält. Wie first ruft es seq zu seinem Argument auf. Es ruft jedoch nicht seq auf sein Ergebnis auf! Das bedeutet, wenn Sie in einer Sequenz, die weniger als zwei Elemente enthält, rest aufrufen, erhalten Sie back () anstelle von nil :

(rest nil)
;;=> ()

(rest '(:foo))
;;=> ()

(rest '(:foo :bar))
;;=> (:bar)

(rest [:foo])
;;=> ()

(rest [:foo :bar])
;;=> (:bar)

(rest {:foo :bar})
;;=> ()

(rest #{:foo})
;;=> ()

Wenn Sie nil zurückgeben möchten, wenn keine weiteren Elemente in einer Sequenz vorhanden sind, können Sie next anstelle von rest :

(next nil)
;;=> nil

(next '(:foo))
;;=> nil

(next [:foo])
;;=> nil

Sie können die cons Funktion verwenden, um eine neue Sequenz zu erstellen, die das erste Argument für das first und das zweite Argument für den rest :

(cons :foo nil)
;;=> (:foo)

(cons :foo (cons :bar nil))
;;=> (:foo :bar)

Clojure bietet eine große Sequenzbibliothek mit vielen Funktionen für den Umgang mit Sequenzen. Das Wichtigste an dieser Bibliothek ist, dass sie mit etwas "seqable" funktioniert, nicht nur mit Listen. Deshalb ist das Konzept einer Sequenz so nützlich. Das bedeutet, dass eine einzelne Funktion, wie zum Beispiel " reduce , für jede Sammlung perfekt funktioniert:

(reduce + '(1 2 3))
;;=> 6

(reduce + [1 2 3])
;;=> 6

(reduce + #{1 2 3})
;;=> 6

Der andere Grund, warum Sequenzen nützlich sind, besteht darin, dass sie, da sie keine bestimmte Implementierung von first und rest erfordern, lazy-Sequenzen zulassen, deren Elemente nur bei Bedarf realisiert werden.

Bei einem Ausdruck, der eine Sequenz erzeugen würde, können Sie diesen Ausdruck in das lazy-seq Makro einschließen, um ein Objekt zu erhalten, das sich wie eine Sequenz verhält. Der Ausdruck wird jedoch nur ausgewertet, wenn er von der Funktion seq (at) aufgefordert wird welcher Stelle es das Ergebnis des Ausdrucks zwischenzuspeichern und nach vorn first und rest Anrufe an die im Cache gespeicherten Ergebnis.

Bei endlichen Sequenzen fungiert eine Lazy-Sequenz normalerweise als äquivalente eifrige Sequenz:

(seq [:foo :bar])
;;=> (:foo :bar)

(lazy-seq [:foo :bar])
;;=> (:foo :bar)

Der Unterschied wird jedoch für unendliche Sequenzen deutlich:

(defn eager-fibonacci [a b]
  (cons a (eager-fibonacci b (+' a b))))

(defn lazy-fibonacci [a b]
  (lazy-seq (cons a (lazy-fibonacci b (+' a b)))))

(take 10 (eager-fibonacci 0 1))
;; java.lang.StackOverflowError:

(take 10 (lazy-fibonacci 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)

Vektoren

Ein Vektor wird durch eckige Klammern angezeigt:

[]
;;=> []

[:foo]
;;=> [:foo]

[:foo :bar]
;;=> [:foo :bar]

[1 (+ 1 1) 3]
;;=> [1 2 3]

Neben der Literal-Syntax können Sie auch die vector verwenden, um einen Vektor zu konstruieren:

(vector)
;;=> []

(vector :foo)
;;=> [:foo]

(vector :foo :bar)
;;=> [:foo :bar]

(vector 1 (+ 1 1) 3)
;;=> [1 2 3]

Sie können mit dem vector? testen, ob etwas ein Vektor vector? Prädikat:

(vector? [])
;;=> true

(vector? [:foo :bar])
;;=> true

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conj fügt Elemente am Ende eines Vektors hinzu:

(conj [] :foo)
;;=> [:foo]

(conj (conj [] :foo) :bar)
;;=> [:foo :bar]

(conj [] :foo :bar)
;;=> [:foo :bar]

count gibt die Anzahl der Elemente in konstanter Zeit zurück:

(count [])
;;=> 0

(count (conj [] :foo))
;;=> 1

(count [:foo :bar])
;;=> 2

Sie können das letzte Element eines Vektors mithilfe von peek :

(peek [])
;;=> nil

(peek [:foo])
;;=> :foo

(peek [:foo :bar])
;;=> :bar

Sie können mit pop einen neuen Vektor ohne das letzte Element erhalten:

(pop [:foo])
;;=> []

(pop [:foo :bar])
;;=> [:foo]

Wenn Sie versuchen, einen leeren Vektor zu platzieren, erhalten Sie eine IllegalStateException :

(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector

Im Gegensatz zu Listen werden Vektoren indiziert. Sie können ein Element eines Vektors über den Index in "konstanter" Zeit erhalten, indem get :

(get [:foo :bar] 0)
;;=> :foo

(get [:foo :bar] 1)
;;=> :bar

(get [:foo :bar] -1)
;;=> nil

(get [:foo :bar] 2)
;;=> nil

Vektoren selbst sind außerdem Funktionen, die einen Index übernehmen und das Element an diesem Index zurückgeben:

([:foo :bar] 0)
;;=> :foo

([:foo :bar] 1)
;;=> :bar

Wenn Sie jedoch einen Vektor mit einem ungültigen Index aufrufen, erhalten Sie eine IndexOutOfBoundsException anstelle von nil :

([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:

([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:

Mit assoc können Sie einen neuen Vektor mit einem anderen Wert an einem bestimmten Index assoc :

(assoc [:foo :bar] 0 42)
;;=> [42 :bar]

(assoc [:foo :bar] 1 42)
;;=> [:foo 42]

Wenn Sie einen Index übergeben, der der count des Vektors entspricht, fügt Clojure das Element so hinzu, als hätten Sie conj . Wenn Sie jedoch einen Index übergeben, der negativ oder größer als die count , erhalten Sie eine IndexOutOfBoundsException :

(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]

(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:

(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:

Sie können eine Sequenz der Elemente in einem Vektor mithilfe von seq :

(seq [])
;;=> nil

(seq [:foo])
;;=> (:foo)

(seq [:foo :bar])
;;=> (:foo :bar)

Da Vektoren indiziert sind, können Sie mit rseq auch eine umgekehrte Reihenfolge der Elemente eines Vektors rseq :

(rseq [])
;;=> nil

(rseq [:foo])
;;=> (:foo)

(rseq [:foo :bar])
;;=> (:bar :foo)

Beachten Sie, dass, obwohl alle Listen Sequenzen sind und Sequenzen auf dieselbe Weise wie Listen angezeigt werden, nicht alle Sequenzen Listen sind!

'(:foo :bar)
;;=> (:foo :bar)

(seq [:foo :bar])
;;=> (:foo :bar)

(list? '(:foo :bar))
;;=> true

(list? (seq [:foo :bar]))
;;=> false

(list? (rseq [:foo :bar]))
;;=> false

Sets

Wie Karten sind Sets assoziativ und ungeordnet. Im Gegensatz zu Karten, die Zuordnungen von Schlüsseln zu Werten enthalten, wird im Wesentlichen eine Zuordnung von Schlüsseln zu sich selbst vorgenommen.

Ein Satz wird durch geschweifte Klammern bezeichnet, denen ein Oktothorpe vorangeht:

#{}
;;=> #{}

#{:foo}
;;=> #{:foo}

#{:foo :bar}
;;=> #{:bar :foo}

Wie bei Karten spielt die Reihenfolge, in der Elemente in einem Literalsatz angezeigt werden, keine Rolle:

(= #{:foo :bar} #{:bar :foo})
;;=> true

Sie können mit dem set? testen, ob etwas ein set? Prädikat:

(set? #{})
;;=> true

(set? #{:foo})
;;=> true

(set? #{:foo :bar})
;;=> true

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

Sie können testen, ob eine Karte ein bestimmtes Element in "konstanter" Zeit contains? indem Sie das contains? Prädikat:

(contains? #{} :foo)
;;=> false

(contains? #{:foo} :foo)
;;=> true

(contains? #{:foo} :bar)
;;=> false

(contains? #{} nil)
;;=> false

(contains? #{nil} nil)
;;=> true

Außerdem sind Mengen selbst Funktionen, die ein Element annehmen und dieses Element zurückgeben, wenn es in der Menge vorhanden ist, oder nil wenn es nicht der nil ist:

(#{} :foo)
;;=> nil

(#{:foo} :foo)
;;=> :foo

(#{:foo} :bar)
;;=> nil

(#{} nil)
;;=> nil

(#{nil} nil)
;;=> nil

Sie können mit conj einen Satz erhalten, der alle Elemente eines vorhandenen Satzes sowie ein weiteres Element enthält:

(conj #{} :foo)
;;=> #{:foo}

(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}

(conj #{:foo} :foo)
;;=> #{:foo}

Sie können disj , um einen Satz disj , der alle Elemente eines vorhandenen Satzes enthält, abzüglich eines Elements:

(disj #{} :foo)
;;=> #{}

(disj #{:foo} :foo)
;;=> #{}

(disj #{:foo} :bar)
;;=> #{:foo}

(disj #{:foo :bar} :foo)
;;=> #{:bar}

(disj #{:foo :bar} :bar)
;;=> #{:foo}

count gibt die Anzahl der Elemente in konstanter Zeit zurück:

(count #{})
;;=> 0

(count (conj #{} :foo))
;;=> 1

(count #{:foo :bar})
;;=> 2

Sie können eine Folge aller Elemente in einem Satz mit seq :

(seq #{})
;;=> nil

(seq #{:foo})
;;=> (:foo)

(seq #{:foo :bar})
;;=> (:bar :foo)

Karten

Im Gegensatz zu der Liste, die eine sequentielle Datenstruktur ist, und dem Vektor, der sowohl sequentiell als auch assoziativ ist, ist die Karte ausschließlich eine assoziative Datenstruktur. Eine Map besteht aus einem Satz von Mappings von Schlüsseln zu Werten. Da alle Schlüssel eindeutig sind, unterstützen Karten die Suche nach "konstanten" Zeiten von Schlüsseln zu Werten.

Eine Karte wird durch geschweifte Klammern gekennzeichnet:

{}
;;=> {}

{:foo :bar}
;;=> {:foo :bar}

{:foo :bar :baz :qux}
;;=> {:foo :bar, :baz :qux}

Jedes Paar von zwei Elementen ist ein Schlüsselwertpaar. So hat beispielsweise die erste Karte oben keine Zuordnungen. Die zweite hat eine Zuordnung, vom Schlüssel :foo bis zum Wert :bar . Die dritte hat zwei Zuordnungen, eine vom Schlüssel :foo zum Wert :bar und eine vom Schlüssel :baz zum Wert :qux . Karten sind von Haus aus ungeordnet, daher spielt es keine Rolle, in welcher Reihenfolge die Zuordnungen angezeigt werden:

(= {:foo :bar :baz :qux}
   {:baz :qux :foo :bar})
;;=> true

Sie können mit der map? testen, ob etwas eine map? Prädikat:

(map? {})
;;=> true

(map? {:foo :bar})
;;=> true

(map? {:foo :bar :baz :qux})
;;=> true

(map? nil)
;;=> false

(map? 42)
;;=> false

(map? :foo)
;;=> false

Sie können testen, ob eine Karte einen bestimmten Schlüssel in "konstanter" Zeit contains? indem Sie das contains? Prädikat:

(contains? {:foo :bar :baz :qux} 42)
;;=> false

(contains? {:foo :bar :baz :qux} :foo)
;;=> true

(contains? {:foo :bar :baz :qux} :bar)
;;=> false

(contains? {:foo :bar :baz :qux} :baz)
;;=> true

(contains? {:foo :bar :baz :qux} :qux)
;;=> false

(contains? {:foo nil} :foo)
;;=> true

(contains? {:foo nil} :bar)
;;=> false

Sie können den mit einem Schlüssel verknüpften Wert mit get :

(get {:foo :bar :baz :qux} 42)
;;=> nil

(get {:foo :bar :baz :qux} :foo)
;;=> :bar

(get {:foo :bar :baz :qux} :bar)
;;=> nil

(get {:foo :bar :baz :qux} :baz)
;;=> :qux

(get {:foo :bar :baz :qux} :qux)
;;=> nil

(get {:foo nil} :foo)
;;=> nil

(get {:foo nil} :bar)
;;=> nil

Darüber hinaus sind Maps selbst Funktionen, die einen Schlüssel annehmen und den mit diesem Schlüssel verknüpften Wert zurückgeben:

({:foo :bar :baz :qux} 42)
;;=> nil

({:foo :bar :baz :qux} :foo)
;;=> :bar

({:foo :bar :baz :qux} :bar)
;;=> nil

({:foo :bar :baz :qux} :baz)
;;=> :qux

({:foo :bar :baz :qux} :qux)
;;=> nil

({:foo nil} :foo)
;;=> nil

({:foo nil} :bar)
;;=> nil

Sie können einen vollständigen Karteneintrag (Schlüssel und Wert zusammen) als Vektor mit zwei Elementen erhalten, indem Sie find :

(find {:foo :bar :baz :qux} 42)
;;=> nil

(find {:foo :bar :baz :qux} :foo)
;;=> [:foo :bar]

(find {:foo :bar :baz :qux} :bar)
;;=> nil

(find {:foo :bar :baz :qux} :baz)
;;=> [:baz :qux]

(find {:foo :bar :baz :qux} :qux)
;;=> nil

(find {:foo nil} :foo)
;;=> [:foo nil]

(find {:foo nil} :bar)
;;=> nil

Sie können den Schlüssel oder Wert aus einer MapEintrag extrahieren mit key oder val jeweils:

(key (find {:foo :bar} :foo))
;;=> :foo

(val (find {:foo :bar} :foo))
;;=> :bar

Obwohl alle Clojure-Karteneinträge Vektoren sind, sind nicht alle Vektoren Karteneinträge. Wenn Sie versuchen, key oder val bei einem ClassCastException Eintrag ClassCastException , der kein Map-Eintrag ist, wird eine ClassCastException :

(key [:foo :bar])
;; java.lang.ClassCastException:

(val [:foo :bar])
;; java.lang.ClassCastException:

Sie können mit dem map-entry? testen, ob etwas ein Karteneintrag ist map-entry? Prädikat:

(map-entry? (find {:foo :bar} :foo))
;;=> true

(map-entry? [:foo :bar])
;;=> false

Sie können assoc , um eine Karte zu erhalten, die alle die gleichen Schlüsselwertpaare wie eine vorhandene Karte enthält, wobei eine Zuordnung hinzugefügt oder geändert wurde:

(assoc {} :foo :bar)
;;=> {:foo :bar}

(assoc (assoc {} :foo :bar) :baz :qux)
;;=> {:foo :bar, :baz :qux}

(assoc {:baz :qux} :foo :bar)
;;=> {:baz :qux, :foo :bar}

(assoc {:foo :bar :baz :qux} :foo 42)
;;=> {:foo 42, :baz :qux}

(assoc {:foo :bar :baz :qux} :baz 42)
;;=> {:foo :bar, :baz 42}

Sie können dissoc , um eine Karte zu erhalten, die alle die gleichen Schlüsselwertpaare wie eine vorhandene Karte enthält, wobei möglicherweise eine Zuordnung entfernt wurde:

(dissoc {:foo :bar :baz :qux} 42)
;;=> {:foo :bar :baz :qux}

(dissoc {:foo :bar :baz :qux} :foo)
;;=> {:baz :qux}

(dissoc {:foo :bar :baz :qux} :bar)
;;=> {:foo :bar :baz :qux}

(dissoc {:foo :bar :baz :qux} :baz)
;;=> {:foo :bar}

(dissoc {:foo :bar :baz :qux} :qux)
;;=> {:foo :bar :baz :qux}

(dissoc {:foo nil} :foo)
;;=> {}

count gibt die Anzahl der Mappings in konstanter Zeit zurück:

(count {})
;;=> 0

(count (assoc {} :foo :bar))
;;=> 1

(count {:foo :bar :baz :qux})
;;=> 2

Sie können eine Reihenfolge aller Einträge in einer Karte mit seq :

(seq {})
;;=> nil

(seq {:foo :bar})
;;=> ([:foo :bar])

(seq {:foo :bar :baz :qux})
;;=> ([:foo :bar] [:baz :qux])

Auch hier sind Karten nicht geordnet, daher ist die Reihenfolge der Elemente in einer Reihenfolge, die Sie erhalten, wenn Sie seq auf einer Karte aufrufen, undefiniert.

Sie können die Tasten eine Sequenz von nur bekommen oder einfach nur die Werte in einer Karte mithilfe von keys oder vals jeweils:

(keys {})
;;=> nil

(keys {:foo :bar})
;;=> (:foo)

(keys {:foo :bar :baz :qux})
;;=> (:foo :baz)

(vals {})
;;=> nil

(vals {:foo :bar})
;;=> (:bar)

(vals {:foo :bar :baz :qux})
;;=> (:bar :qux)

Clojure 1.9 fügt eine Literal-Syntax hinzu, um eine Karte, in der die Schlüssel denselben Namespace verwenden, übersichtlicher darzustellen. Beachten Sie, dass die Map in beiden Fällen identisch ist (die Map "kennt" den Standard-Namespace nicht). Dies ist lediglich eine Vereinfachung der Syntax.

;; typical map syntax
(def p {:person/first"Darth" :person/last "Vader" :person/email "[email protected]"})

;; namespace map literal syntax
(def p #:person{:first "Darth" :last "Vader" :email "[email protected]"})


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow