Recherche…


Syntaxe

  • '()()
  • '(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"} (les entrées sont triées par clé lorsqu'elles sont utilisées comme une séquence)
  • #{}#{}
  • #{1 2 3 4 5}#{4 3 2 5 1} (non ordonné)
  • ( hash-set 1 2 3 4 5)#{2 5 4 1 3} (non ordonné)
  • ( sorted-set 2 5 4 3 1)#{1 2 3 4 5}

Collections

Toutes les collections Clojure intégrées sont immuables et hétérogènes, ont une syntaxe littérale et prennent en charge les fonctions conj , count et seq .

  • conj renvoie une nouvelle collection équivalente à une collection existante avec un élément "ajouté", soit dans le temps "constant" ou logarithmique. Ce que cela signifie exactement dépend de la collection.
  • count renvoie le nombre d'éléments d'une collection, en temps constant.
  • seq renvoie nil pour une collection vide ou une séquence d'éléments pour une collection non vide, à temps constant.

Des listes

Une liste est indiquée par des parenthèses:

()
;;=> ()

Une liste de Clojure est une liste à liens simples . conj "joint" un nouvel élément à la collection dans l'emplacement le plus efficace. Pour les listes, c'est au début:

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

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

Contrairement aux autres collections, les listes non vides sont évaluées comme des appels à des formulaires, macros ou fonctions spéciaux lorsqu'elles sont évaluées. Par conséquent, tant que (:foo) est la représentation littérale de la liste contenant :foo comme seul élément, l'évaluation de (:foo) dans une REPL provoquera une IllegalArgumentException car un mot clé ne peut pas être appelé comme fonction nullary .

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

Pour empêcher Clojure d’évaluer une liste non vide, vous pouvez la quote :

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

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

Malheureusement, les éléments ne sont pas évalués:

(+ 1 1)
;;=> 2

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

Pour cette raison, vous voudrez généralement utiliser list , une fonction variadic qui évalue tous ses arguments et utilise ces résultats pour construire une liste:

(list)
;;=> ()

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

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

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

count renvoie le nombre d'éléments, en temps constant:

(count ())
;;=> 0

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

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

Vous pouvez tester si quelque chose est une liste en utilisant la list? prédicat:

(list? ())
;;=> true

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

(list? nil)
;;=> false

(list? 42)
;;=> false

(list? :foo)
;;=> false

Vous pouvez obtenir le premier élément d'une liste en utilisant peek :

(peek ())
;;=> nil

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

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

Vous pouvez obtenir une nouvelle liste sans le premier élément en utilisant pop :

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

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

Notez que si vous essayez de faire pop une liste vide, vous obtiendrez une IllegalStateException :

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

Enfin, toutes les listes sont des séquences, vous pouvez donc tout faire avec une liste que vous pouvez faire avec toute autre séquence. En effet, à l'exception de la liste vide, l'appel de seq sur une liste renvoie exactement le même objet:

(seq ())
;;=> nil

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

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

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

Séquences

Une séquence ressemble beaucoup à une liste: c'est un objet immuable qui peut vous donner son first élément ou le rest de ses éléments en temps constant. Vous pouvez également cons truct une nouvelle séquence d'une séquence existante et un élément de coller au début.

Vous pouvez tester si quelque chose est une séquence en utilisant le seq? prédicat:

(seq? nil)
;;=> false

(seq? 42)
;;=> false

(seq? :foo)
;;=> false

Comme vous le savez déjà, les listes sont des séquences:

(seq? ())
;;=> true

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

Tout ce que vous obtenez en appelant seq ou rseq ou des keys ou des vals sur une collection non vide est également une séquence:

(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

Rappelez-vous que toutes les listes sont des séquences, mais toutes les séquences ne sont pas des listes. Alors que les listes prennent en charge les fonctions de peek et de pop et count en temps constant, en général, une séquence n'a pas besoin de prendre en charge l'une de ces fonctions. Si vous essayez d'appeler peek ou pop sur une séquence qui ne prend pas également en charge l'interface de pile de Clojure, vous obtiendrez une 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

Si vous appelez count sur une séquence qui n'implémente pas le count en temps constant, vous n'obtiendrez pas d'erreur. Clojure traversera toute la séquence jusqu'à la fin, puis retournera le nombre d'éléments qu'il a parcourus. Cela signifie que, pour les séquences générales, le count est linéaire, pas constant, le temps. Vous pouvez tester si quelque chose prend en charge le count temps constant en utilisant le counted? prédicat:

(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

Comme mentionné ci-dessus, vous pouvez utiliser d' first pour obtenir le premier élément d'une séquence. Notez que le first appelera seq sur leur argument, donc il peut être utilisé sur tout "seqable", pas seulement sur les séquences réelles:

(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

Comme mentionné ci-dessus, vous pouvez utiliser rest pour obtenir une séquence contenant tous les éléments sauf le premier élément d'une séquence existante. Comme first , il appelle seq sur son argument. Cependant, il n'appelle pas seq sur son résultat! Cela signifie que si vous appelez rest sur une séquence contenant moins de deux éléments, vous récupérerez () au lieu de nil :

(rest nil)
;;=> ()

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

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

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

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

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

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

Si vous voulez récupérer nil quand il n'y a plus d'éléments dans une séquence, vous pouvez utiliser next au lieu de rest :

(next nil)
;;=> nil

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

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

Vous pouvez utiliser la fonction cons pour créer une nouvelle séquence qui renverra son premier argument pour le first et son deuxième argument pour le rest :

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

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

Clojure fournit une grande bibliothèque de séquences avec de nombreuses fonctions pour gérer les séquences. L'important à propos de cette bibliothèque est qu'elle fonctionne avec tout ce qui peut être "séqé", pas seulement les listes. C'est pourquoi le concept d'une séquence est si utile; cela signifie qu'une seule fonction, comme reduce , fonctionne parfaitement sur n'importe quelle collection:

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

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

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

L'autre raison pour laquelle les séquences sont utiles est que, puisqu'elles ne requièrent aucune implémentation particulière du first et du rest , elles permettent des séquences paresseuses dont les éléments ne sont réalisés que lorsque cela est nécessaire.

Étant donné une expression qui créerait une séquence, vous pouvez envelopper cette expression dans la macro lazy-seq pour obtenir un objet qui agit comme une séquence, mais n'évaluera réellement cette expression que lorsque la fonction seq le demandera, à quel point il va mettre en cache le résultat de l'expression et en avant first et rest les appels vers le résultat mis en cache.

Pour les séquences finies, une séquence paresseuse agit généralement comme une séquence équivalente:

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

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

Cependant, la différence devient évidente pour des séquences infinies:

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

Vecteurs

Un vecteur est indiqué par des crochets:

[]
;;=> []

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

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

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

En plus de la syntaxe littérale, vous pouvez également utiliser la fonction vector pour construire un vecteur:

(vector)
;;=> []

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

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

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

Vous pouvez tester si quelque chose est un vecteur en utilisant le vector? prédicat:

(vector? [])
;;=> true

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

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conj ajoute des éléments à la fin d'un vecteur:

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

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

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

count renvoie le nombre d'éléments, en temps constant:

(count [])
;;=> 0

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

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

Vous pouvez obtenir le dernier élément d'un vecteur en utilisant peek :

(peek [])
;;=> nil

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

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

Vous pouvez obtenir un nouveau vecteur sans le dernier élément en utilisant pop :

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

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

Notez que si vous essayez de faire apparaître un vecteur vide, vous obtiendrez une IllegalStateException :

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

Contrairement aux listes, les vecteurs sont indexés. Vous pouvez obtenir un élément d'un vecteur par index dans le temps "constant" en utilisant get :

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

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

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

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

De plus, les vecteurs eux-mêmes sont des fonctions qui prennent un index et renvoient l'élément à cet index:

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

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

Cependant, si vous appelez un vecteur avec un index non valide, vous obtiendrez une IndexOutOfBoundsException au lieu de nil :

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

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

Vous pouvez obtenir un nouveau vecteur avec une valeur différente à un index particulier en utilisant assoc :

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

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

Si vous passez un index égal au count de vecteurs, Clojure ajoutera l'élément comme si vous aviez utilisé conj . Toutefois, si vous transmettez un index négatif ou supérieur au count , vous obtenez une 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:

Vous pouvez obtenir une séquence des éléments dans un vecteur en utilisant seq :

(seq [])
;;=> nil

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

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

Comme les vecteurs sont indexés, vous pouvez également obtenir une séquence inversée des éléments d'un vecteur en utilisant rseq :

(rseq [])
;;=> nil

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

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

Notez que, bien que toutes les listes soient des séquences et que les séquences soient affichées de la même manière que les listes, toutes les séquences ne sont pas des listes!

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

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

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

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

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

Ensembles

Comme les cartes, les ensembles sont associatifs et non ordonnés. Contrairement aux cartes, qui contiennent des correspondances entre les clés et les valeurs, elles définissent essentiellement la correspondance entre les clés et elles-mêmes.

Un ensemble est désigné par des accolades précédé d'un octothorpe:

#{}
;;=> #{}

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

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

Comme pour les cartes, l'ordre dans lequel les éléments apparaissent dans un ensemble littéral n'a pas d'importance:

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

Vous pouvez tester si quelque chose est un ensemble en utilisant l' set? prédicat:

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

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

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

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

Vous pouvez tester si une carte contient un élément donné dans le temps "constant" en utilisant le contains? prédicat:

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

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

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

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

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

De plus, les ensembles eux-mêmes sont des fonctions qui prennent un élément et renvoient cet élément s'il est présent dans l'ensemble, ou nil s'il ne l'est pas:

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

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

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

(#{} nil)
;;=> nil

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

Vous pouvez utiliser conj pour obtenir un ensemble contenant tous les éléments d'un ensemble existant, plus un élément supplémentaire:

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

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

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

Vous pouvez utiliser disj pour obtenir un ensemble disj tous les éléments d'un ensemble existant, moins un élément:

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

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

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

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

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

count renvoie le nombre d'éléments, en temps constant:

(count #{})
;;=> 0

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

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

Vous pouvez obtenir une séquence de tous les éléments d'un ensemble en utilisant seq :

(seq #{})
;;=> nil

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

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

Plans

Contrairement à la liste, qui est une structure de données séquentielle, et le vecteur, qui est à la fois séquentiel et associatif, la carte est exclusivement une structure de données associative. Une carte consiste en un ensemble de correspondances entre les clés et les valeurs. Toutes les clés sont uniques, donc les cartes prennent en charge la recherche "constante" entre les clés et les valeurs.

Une carte est indiquée par des accolades:

{}
;;=> {}

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

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

Chaque paire de deux éléments est une paire clé-valeur. Ainsi, par exemple, la première carte ci-dessus n'a pas de correspondance. Le second a un mapping, de la clé :foo à la valeur :bar . Le troisième a deux mappages, un de la clé :foo à la valeur :bar , et un de la clé :baz à la valeur :qux . Les cartes sont intrinsèquement non ordonnées, donc l'ordre dans lequel les correspondances apparaissent n'a pas d'importance:

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

Vous pouvez tester si quelque chose est une carte en utilisant la map? prédicat:

(map? {})
;;=> true

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

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

(map? nil)
;;=> false

(map? 42)
;;=> false

(map? :foo)
;;=> false

Vous pouvez tester si une carte contient une clé donnée dans le temps "constant" en utilisant le contains? prédicat:

(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

Vous pouvez obtenir la valeur associée à une clé en utilisant 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

De plus, les cartes elles-mêmes sont des fonctions qui prennent une clé et renvoient la valeur associée à cette clé:

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

Vous pouvez obtenir une entrée de carte complète (clé et valeur ensemble) en tant que vecteur à deux éléments en utilisant 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

Vous pouvez extraire la clé ou la valeur d'une entrée de carte en utilisant la key ou val respectivement:

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

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

Notez que, bien que toutes les entrées de carte Clojure soient des vecteurs, tous les vecteurs ne sont pas des entrées de carte. Si vous essayez d'appeler key ou val sur quelque chose qui n'est pas une entrée de carte, vous obtiendrez une ClassCastException :

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

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

Vous pouvez tester si quelque chose est une entrée de carte en utilisant l' map-entry? prédicat:

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

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

Vous pouvez utiliser assoc pour obtenir une carte ayant toutes les mêmes paires clé-valeur qu'une carte existante, avec un mappage ajouté ou modifié:

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

Vous pouvez utiliser dissoc pour obtenir une carte ayant toutes les mêmes paires clé-valeur qu'une carte existante, avec éventuellement un mappage supprimé:

(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 renvoie le nombre de mappages, en temps constant:

(count {})
;;=> 0

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

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

Vous pouvez obtenir une séquence de toutes les entrées dans une carte en utilisant seq :

(seq {})
;;=> nil

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

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

Encore une fois, les cartes ne sont pas ordonnées, de sorte que l'ordre des éléments dans une séquence obtenue en appelant seq sur une carte n'est pas défini.

Vous pouvez obtenir une séquence de seulement les clés ou simplement les valeurs dans une carte en utilisant respectivement des keys ou des vals :

(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 ajoute une syntaxe littérale pour représenter de manière plus concise une carte où les clés partagent le même espace de noms. Notez que la carte dans les deux cas est identique (la carte ne "connaît" pas l'espace de nommage par défaut), ceci est simplement une commodité syntaxique.

;; 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow