Zoeken…


Syntaxis

  • '()()
  • '(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"} (vermeldingen worden per sleutel gesorteerd als ze als een reeks worden gebruikt)
  • #{}#{}
  • #{1 2 3 4 5}#{4 3 2 5 1} (ongeordend)
  • ( hash-set 1 2 3 4 5)#{2 5 4 1 3} (ongeordend)
  • ( sorted-set 2 5 4 3 1)#{1 2 3 4 5}

collecties

Alle ingebouwde Clojure-collecties zijn onveranderlijk en heterogeen, hebben een letterlijke syntaxis en ondersteunen de conj , count en seq functies.

  • conj retourneert een nieuwe collectie die equivalent is aan een bestaande collectie met een item "toegevoegd", in "constante" of logaritmische tijd. Wat dit precies betekent, hangt af van de collectie.
  • count retourneert het aantal items in een verzameling, in constante tijd.
  • seq retourneert nil voor een lege verzameling, of een reeks items voor een niet-lege verzameling, in constante tijd.

lijsten

Een lijst wordt tussen haakjes aangegeven:

()
;;=> ()

Een Clojure-lijst is een afzonderlijk gekoppelde lijst . conj "verbindt" een nieuw element met de verzameling op de meest efficiënte locatie. Voor lijsten is dit aan het begin:

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

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

In tegenstelling tot andere collecties worden niet-lege lijsten geëvalueerd als aanroepen naar speciale formulieren, macro's of functies wanneer ze worden geëvalueerd. Terwijl (:foo) dus de letterlijke weergave is van de lijst met :foo als het enige item, zal het evalueren van (:foo) in een REPL ertoe leiden dat een IllegalArgumentException wordt gegenereerd omdat een trefwoord niet als een nullary-functie kan worden opgeroepen.

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

Om te voorkomen dat Clojure een niet-lege lijst evalueert, kunt u deze quote :

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

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

Helaas worden hierdoor de elementen niet geëvalueerd:

(+ 1 1)
;;=> 2

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

Om deze reden wilt u meestal list , een variadische functie die alle argumenten evalueert en die resultaten gebruikt om een lijst samen te stellen:

(list)
;;=> ()

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

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

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

count geeft het aantal items terug, in constante tijd:

(count ())
;;=> 0

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

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

U kunt testen of iets een lijst is met behulp van de list? predikaat:

(list? ())
;;=> true

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

(list? nil)
;;=> false

(list? 42)
;;=> false

(list? :foo)
;;=> false

U kunt het eerste element van een lijst krijgen met behulp van peek :

(peek ())
;;=> nil

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

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

U kunt een nieuwe lijst krijgen zonder het eerste element met behulp van pop :

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

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

Merk op dat als u probeert om pop een lege lijst, krijg je een te krijgen IllegalStateException :

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

Ten slotte zijn alle lijsten reeksen, dus u kunt alles doen met een lijst die u met elke andere reeks kunt doen. Inderdaad, met uitzondering van de lege lijst, retourneert seq op een lijst exact hetzelfde object:

(seq ())
;;=> nil

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

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

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

Opeenvolgingen

Een reeks lijkt erg op een lijst: het is een onveranderlijk object dat u in constante tijd het first element of de rest van de elementen kan geven. U kunt ook cons truct een nieuwe reeks van een bestaande reeks en een item dat stok bij het begin.

Je kunt testen of iets een reeks is met behulp van de seq? predikaat:

(seq? nil)
;;=> false

(seq? 42)
;;=> false

(seq? :foo)
;;=> false

Zoals u al weet, zijn lijsten reeksen:

(seq? ())
;;=> true

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

Alles wat je krijgt door seq of rseq of keys of vals op een niet-lege verzameling aan te roepen, is ook een reeks:

(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

Onthoud dat alle lijsten reeksen zijn, maar niet alle reeksen lijsten zijn. Hoewel lijsten peek en pop en in constante tijd count , hoeft een reeks over het algemeen geen van deze functies te ondersteunen. Als u probeert te bellen peek of pop op een sequentie die ook niet Clojure's stack-interface ondersteunt, dan heb je een te krijgen 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

Als u count oproept in een reeks die count in constante tijd implementeert, krijgt u geen foutmelding; in plaats daarvan zal Clojure de hele reeks doorlopen totdat deze het einde bereikt, en vervolgens het aantal elementen teruggeven dat het heeft doorlopen. Dit betekent dat voor algemene sequenties de count lineair is, niet constant, de tijd. U kunt testen of iets constant-time count met behulp van de counted? predikaat:

(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

Zoals hierboven vermeld, kunt u first gebruiken om het eerste element van een reeks te krijgen. Merk op dat first seq aangeroepen op hun argument, dus het kan worden gebruikt op alles wat "seqable" is, niet alleen werkelijke reeksen:

(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

Zoals hierboven vermeld, kunt u rest gebruiken om een reeks te krijgen die alles behalve het eerste element van een bestaande reeks bevat. Zoals first , roept het seq op zijn argument. Het roept echter geen seq op het resultaat! Dit betekent dat als je rest in een reeks die minder dan twee items bevat, je terug () plaats van nil :

(rest nil)
;;=> ()

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

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

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

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

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

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

Als je weer nil wilt krijgen wanneer er geen elementen meer in een reeks zijn, kun je de next plaats van de rest :

(next nil)
;;=> nil

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

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

Je kunt de functie cons gebruiken om een nieuwe reeks te maken die het eerste argument voor het first en het tweede argument voor de rest retourneert:

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

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

Clojure biedt een grote reeks bibliotheek met veel functies voor het omgaan met reeksen. Het belangrijkste van deze bibliotheek is dat deze werkt met alles "seqable", niet alleen lijsten. Daarom is het concept van een reeks zo nuttig; het betekent dat een enkele functie, zoals reduce , perfect werkt bij elke verzameling:

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

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

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

De andere reden dat reeksen nuttig zijn, is dat, omdat ze geen specifieke implementatie van first en rest vereisen, ze luie reeksen toestaan waarvan de elementen alleen worden gerealiseerd wanneer dat nodig is.

Gegeven een uitdrukking die een reeks zou creëren, kunt u die uitdrukking in de lazy-seq macro wikkelen om een object te krijgen dat als een reeks fungeert, maar die uitdrukking alleen daadwerkelijk evalueren wanneer het wordt gevraagd door de seq functie, op welk punt het het resultaat van de uitdrukking in de cache opslaat en first doorstuurt en de rest aanroepen naar het in de cache opgeslagen resultaat.

Voor eindige reeksen werkt een luie reeks meestal hetzelfde als een vergelijkbare enthousiaste reeks:

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

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

Het verschil wordt echter duidelijk voor oneindige reeksen:

(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)

vectoren

Een vector wordt aangegeven met vierkante haken:

[]
;;=> []

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

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

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

Naast de letterlijke syntaxis kunt u ook de vector om een vector te construeren:

(vector)
;;=> []

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

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

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

U kunt testen of iets een vector is met behulp van de vector? predikaat:

(vector? [])
;;=> true

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

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conj voegt elementen toe aan het einde van een vector:

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

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

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

count geeft het aantal items terug, in constante tijd:

(count [])
;;=> 0

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

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

Je kunt het laatste element van een vector krijgen met behulp van peek :

(peek [])
;;=> nil

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

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

Je kunt een nieuwe vector krijgen zonder het laatste element met behulp van pop :

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

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

Merk op dat als je probeert een lege vector te laten verschijnen, je een IllegalStateException :

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

In tegenstelling tot lijsten worden vectoren geïndexeerd. Je kunt een element van een vector per index krijgen in "constante" tijd met get :

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

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

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

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

Bovendien zijn vectoren zelf functies die een index nemen en het element op die index teruggeven:

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

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

Als u echter een vector met een ongeldige index IndexOutOfBoundsException , krijgt u een IndexOutOfBoundsException plaats van nil :

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

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

U kunt een nieuwe vector met een andere waarde op een bepaalde index krijgen met behulp van assoc :

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

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

Als u een index doorgeeft die gelijk is aan het count van de vector, voegt Clojure het element toe alsof u conj had gebruikt. Als u echter een index doorgeeft die negatief of groter is dan de count , krijgt u een 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:

Je kunt een reeks items in een vector krijgen met seq :

(seq [])
;;=> nil

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

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

Omdat vectoren worden geïndexeerd, kunt u ook een omgekeerde volgorde van items van een vector krijgen met behulp van rseq :

(rseq [])
;;=> nil

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

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

Hoewel alle lijsten reeksen zijn en reeksen op dezelfde manier worden weergegeven als lijsten, zijn niet alle reeksen lijsten!

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

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

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

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

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

sets

Net als kaarten zijn sets associatief en ongeordend. In tegenstelling tot kaarten, die toewijzingen van sleutels tot waarden bevatten, stelt de kaart in wezen de kaart in van sleutels tot zichzelf.

Een set wordt aangegeven met accolades voorafgegaan door een octothorpe:

#{}
;;=> #{}

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

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

Net als bij kaarten, maakt de volgorde waarin elementen in een letterlijke set verschijnen niet uit:

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

U kunt testen of iets een set is met behulp van de set? predikaat:

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

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

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

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

U kunt testen of een kaart een bepaald item in "constante" tijd contains? met behulp van de contains? predikaat:

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

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

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

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

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

Bovendien zijn sets zelf functies die een element nemen en dat element retourneren als het in de set aanwezig is, of nil als het niet is:

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

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

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

(#{} nil)
;;=> nil

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

Je kunt conj gebruiken om een set te krijgen die alle elementen van een bestaande set bevat, plus een extra item:

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

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

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

Je kunt disj gebruiken om een set te krijgen die alle elementen van een bestaande set bevat, min één item:

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

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

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

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

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

count geeft het aantal elementen terug, in constante tijd:

(count #{})
;;=> 0

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

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

Je kunt een reeks van alle elementen in een set krijgen met seq :

(seq #{})
;;=> nil

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

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

Kaarten

In tegenstelling tot de lijst, die een sequentiële datastructuur is, en de vector, die zowel sequentieel als associatief is, is de kaart uitsluitend een associatieve datastructuur. Een kaart bestaat uit een reeks toewijzingen van sleutels tot waarden. Alle sleutels zijn uniek, dus kaarten ondersteunen het "constant" zoeken van sleutels naar waarden.

Een kaart wordt aangegeven met accolades:

{}
;;=> {}

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

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

Elk paar van twee elementen is een sleutel / waarde-paar. De eerste kaart hierboven heeft bijvoorbeeld geen toewijzingen. De tweede heeft één afbeelding, van de sleutel :foo tot de waarde :bar . De derde heeft twee toewijzingen, een van de sleutel :foo tot de waarde :bar en een van de sleutel :baz tot de waarde :qux . Kaarten zijn inherent ongeordend, dus de volgorde waarin de toewijzingen worden weergegeven, doet er niet toe:

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

U kunt testen of iets een kaart is met behulp van de map? predikaat:

(map? {})
;;=> true

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

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

(map? nil)
;;=> false

(map? 42)
;;=> false

(map? :foo)
;;=> false

U kunt testen of een kaart een gegeven sleutel in "constante" tijd contains? met behulp van de contains? predikaat:

(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

U kunt de waarde krijgen die aan een sleutel is gekoppeld met 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

Bovendien zijn kaarten zelf functies die een sleutel gebruiken en de waarde retourneren die aan die sleutel is gekoppeld:

({: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

U kunt een volledig kaartitem (sleutel en waarde samen) krijgen als een vector met twee elementen met behulp van 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

U kunt de sleutel of waarde uit een kaartitem extraheren met respectievelijk key of val :

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

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

Merk op dat, hoewel alle Clojure-kaartitems vectoren zijn, niet alle vectoren kaartitems zijn. Als u key of val probeert aan te roepen op iets dat geen ClassCastException , krijgt u een ClassCastException :

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

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

U kunt testen of iets een kaartinvoer is met behulp van de map-entry? predikaat:

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

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

U kunt assoc gebruiken om een kaart te krijgen die allemaal dezelfde sleutel / waarde-paren heeft als een bestaande kaart, met één toewijzing toegevoegd of gewijzigd:

(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}

Je kunt dissoc gebruiken om een kaart te krijgen die allemaal dezelfde sleutel / waarde-paren heeft als een bestaande kaart, met mogelijk één kaart verwijderd:

(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 geeft het aantal toewijzingen terug, in constante tijd:

(count {})
;;=> 0

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

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

U kunt een reeks van alle vermeldingen op een kaart krijgen met seq :

(seq {})
;;=> nil

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

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

Nogmaals, kaarten zijn niet geordend, dus de volgorde van de items in een reeks die u krijgt door seq op een kaart te bellen, is niet gedefinieerd.

U kunt een reeks van alleen de toetsen of alleen de waarden in een kaart krijgen met behulp van keys of vals , respectievelijk:

(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 voegt een letterlijke syntaxis toe voor een meer beknopte weergave van een kaart waarbij de toetsen dezelfde naamruimte delen. Merk op dat de kaart in beide gevallen identiek is (de kaart "kent" de standaardnaamruimte niet), dit is slechts een syntactisch gemak.

;; 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow