Ricerca…


Sintassi

  • '()()
  • '(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"} (le voci sono ordinate per tasto quando usate come sequenza)
  • #{}#{}
  • #{1 2 3 4 5}#{4 3 2 5 1} (non ordinato)
  • ( hash-set 1 2 3 4 5)#{2 5 4 1 3} (non ordinato)
  • ( sorted-set 2 5 4 3 1)#{1 2 3 4 5}

collezioni

Tutte le raccolte Clojure incorporate sono immutabili ed eterogenee, hanno una sintassi letterale e supportano le funzioni conj , count e seq .

  • conj restituisce una nuova collezione che è equivalente a una collezione esistente con un elemento "aggiunto", in "tempo costante" o logaritmico. Cosa significa esattamente questo dipende dalla collezione.
  • count restituisce il numero di elementi in una raccolta, in tempo costante.
  • seq restituisce nil per una raccolta vuota o una sequenza di elementi per una raccolta non vuota, in tempo costante.

elenchi

Una lista è denotata da parentesi:

()
;;=> ()

Una lista di Clojure è una lista concatenata . conj "unisce" un nuovo elemento alla collezione nella posizione più efficiente. Per gli elenchi, questo è all'inizio:

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

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

A differenza di altre raccolte, gli elenchi non vuoti vengono valutati come chiamate a moduli speciali, macro o funzioni quando vengono valutati. Pertanto, mentre (:foo) è la rappresentazione letterale della lista che contiene :foo come unico elemento, la valutazione (:foo) in un REPL causerà il IllegalArgumentException di IllegalArgumentException perché una parola chiave non può essere invocata come una funzione nulla .

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

Per evitare che Clojure valuti un elenco non vuoto, puoi quote :

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

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

Sfortunatamente, questo non causa la valutazione degli elementi:

(+ 1 1)
;;=> 2

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

Per questo motivo, di solito vuoi usare la list , una funzione variadica che valuta tutti i suoi argomenti e usa quei risultati per costruire una lista:

(list)
;;=> ()

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

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

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

count restituisce il numero di elementi, in tempo costante:

(count ())
;;=> 0

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

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

Puoi verificare se qualcosa è una lista usando l' list? predicato:

(list? ())
;;=> true

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

(list? nil)
;;=> false

(list? 42)
;;=> false

(list? :foo)
;;=> false

È possibile ottenere il primo elemento di una lista usando peek :

(peek ())
;;=> nil

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

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

Puoi ottenere una nuova lista senza il primo elemento usando pop :

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

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

Si noti che se si tenta di pop un elenco vuoto, si otterrà un IllegalStateException :

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

Infine, tutte le liste sono sequenze, quindi puoi fare tutto con una lista che puoi fare con qualsiasi altra sequenza. Infatti, con l'eccezione della lista vuota, chiamare seq su una lista restituisce lo stesso identico oggetto:

(seq ())
;;=> nil

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

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

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

sequenze

Una sequenza è molto simile a una lista: è un oggetto immutabile che può darti il ​​suo first elemento o il rest dei suoi elementi in un tempo costante. È possibile anche cons truct una nuova sequenza da una sequenza esistente e un elemento di attenersi al principio.

Puoi verificare se qualcosa è una sequenza usando il seq? predicato:

(seq? nil)
;;=> false

(seq? 42)
;;=> false

(seq? :foo)
;;=> false

Come già sai, le liste sono sequenze:

(seq? ())
;;=> true

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

Tutto ciò che ottieni chiamando seq o rseq o keys o vals su una raccolta non vuota è anche una sequenza:

(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

Ricorda che tutte le liste sono sequenze, ma non tutte le sequenze sono elenchi. Mentre le liste supportano lo peek e il pop e count in un tempo costante, in generale, una sequenza non ha bisogno di supportare nessuna di quelle funzioni. Se provi a chiamare peek o pop su una sequenza che non supporta anche l'interfaccia stack di Clojure, otterrai una 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

Se si chiama count su una sequenza che non implementa il count in tempo costante, non si otterrà un errore; invece, Clojure attraverserà l'intera sequenza fino a raggiungere la fine, quindi restituirà il numero di elementi che ha attraversato. Ciò significa che, per le sequenze generali, il count è un tempo lineare, non costante. È possibile verificare se qualcosa supporta il count tempo costante utilizzando il counted? predicato:

(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

Come accennato in precedenza, è possibile utilizzare first per ottenere il primo elemento di una sequenza. Nota che first chiameremo seq sul loro argomento, quindi può essere usato su qualsiasi cosa "seqable", non solo sulle sequenze effettive:

(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

Inoltre, come menzionato sopra, puoi usare il rest per ottenere una sequenza che contiene tutto tranne il primo elemento di una sequenza esistente. Come first , chiama seq sulla sua argomentazione. Tuttavia, non chiama seq sul suo risultato! Ciò significa che, se chiami il rest su una sequenza che contiene meno di due elementi, tornerai indietro () invece di nil :

(rest nil)
;;=> ()

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

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

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

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

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

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

Se si vuole tornare nil , quando non ci sono più elementi in una sequenza, è possibile utilizzare next posto di rest :

(next nil)
;;=> nil

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

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

È possibile utilizzare la funzione cons per creare una nuova sequenza che restituirà il primo argomento per il first e il secondo argomento per il rest :

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

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

Clojure offre una grande libreria di sequenze con molte funzioni per gestire le sequenze. La cosa importante di questa libreria è che funziona con qualsiasi cosa "seqable", non solo con le liste. Ecco perché il concetto di una sequenza è così utile; significa che una singola funzione, come reduce , funziona perfettamente su qualsiasi raccolta:

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

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

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

L'altra ragione per cui le sequenze sono utili è che, poiché non impongono alcuna particolare implementazione del first e del rest , consentono sequenze pigre i cui elementi vengono realizzati solo quando necessario.

Data un'espressione che creerebbe una sequenza, puoi avvolgere quell'espressione nella macro lazy-seq per ottenere un oggetto che si comporta come una sequenza, ma in realtà valuterà quell'espressione solo quando viene richiesta dalla funzione seq , a che punto sarà cache il risultato dell'espressione e in avanti first e rest chiamate al risultato in cache.

Per le sequenze finite, una sequenza lenta di solito agisce come una sequenza desiderosa equivalente:

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

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

Tuttavia, la differenza diventa evidente per le sequenze infinite:

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

Vettori

Un vettore è indicato da parentesi quadre:

[]
;;=> []

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

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

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

Inoltre, utilizzando la sintassi letterale, puoi anche utilizzare la funzione vector per costruire un vettore:

(vector)
;;=> []

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

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

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

Puoi verificare se qualcosa è un vettore che usa il vector? predicato:

(vector? [])
;;=> true

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

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conj aggiunge elementi alla fine di un vettore:

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

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

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

count restituisce il numero di elementi, in tempo costante:

(count [])
;;=> 0

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

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

Puoi ottenere l'ultimo elemento di un vettore usando la peek :

(peek [])
;;=> nil

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

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

Puoi ottenere un nuovo vettore senza l'ultimo elemento usando pop :

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

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

Nota che se provi a far IllegalStateException un vettore vuoto, otterrai una IllegalStateException :

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

A differenza delle liste, i vettori sono indicizzati. Puoi ottenere un elemento di un vettore per indice in tempo "costante" usando get :

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

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

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

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

Inoltre, i vettori stessi sono funzioni che prendono un indice e restituiscono l'elemento in quell'indice:

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

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

Tuttavia, se chiami un vettore con un indice non valido, otterrai un valore IndexOutOfBoundsException anziché nil :

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

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

Puoi ottenere un nuovo vettore con un valore diverso in un indice particolare usando assoc :

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

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

Se passi un indice uguale al count del vettore, Clojure aggiungerà l'elemento come se avessi usato il conj . Tuttavia, se si passa un indice negativo o superiore al count , si otterrà un valore 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:

Puoi ottenere una sequenza degli elementi in un vettore usando seq :

(seq [])
;;=> nil

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

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

Poiché i vettori sono indicizzati, puoi anche ottenere una sequenza invertita degli elementi di un vettore usando rseq :

(rseq [])
;;=> nil

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

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

Si noti che, sebbene tutte le liste siano sequenze e le sequenze siano visualizzate allo stesso modo delle liste, non tutte le sequenze sono elenchi!

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

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

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

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

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

Imposta

Come le mappe, gli insiemi sono associativi e non ordinati. A differenza delle mappe, che contengono mappature da chiavi a valori, imposta essenzialmente la mappa da chiavi a se stesse.

Un set è denotato da parentesi graffe precedute da un octothorpe:

#{}
;;=> #{}

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

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

Come con le mappe, l'ordine in cui gli elementi appaiono in un set letterale non ha importanza:

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

Puoi verificare se qualcosa è un set usando il set? predicato:

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

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

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

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

È possibile verificare se una mappa contiene un dato elemento in "costante" utilizzando il contains? predicato:

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

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

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

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

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

Inoltre, gli insiemi stessi sono funzioni che accettano un elemento e restituiscono quell'elemento se è presente nell'insieme, o nil se non lo è:

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

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

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

(#{} nil)
;;=> nil

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

Puoi usare conj per ottenere un set che ha tutti gli elementi di un set esistente, oltre a un elemento aggiuntivo:

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

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

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

Puoi usare disj per ottenere un set che ha tutti gli elementi di un set esistente, meno un elemento:

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

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

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

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

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

count restituisce il numero di elementi, in tempo costante:

(count #{})
;;=> 0

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

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

Puoi ottenere una sequenza di tutti gli elementi in un set usando seq :

(seq #{})
;;=> nil

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

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

Mappe

A differenza della lista, che è una struttura dati sequenziale, e del vettore, che è sia sequenziale che associativo, la mappa è esclusivamente una struttura di dati associativa. Una mappa consiste in un insieme di mappature dalle chiavi ai valori. Tutte le chiavi sono univoche, quindi le mappe supportano la ricerca "costante" -time dalle chiavi ai valori.

Una mappa è denotata da parentesi graffe:

{}
;;=> {}

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

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

Ogni coppia di due elementi è una coppia chiave-valore. Quindi, ad esempio, la prima mappa in alto non ha mappature. Il secondo ha una mappatura, dalla chiave :foo al valore :bar . Il terzo ha due mapping, uno dalla chiave :foo al valore :bar , e uno dalla chiave :baz al valore :qux . Le mappe sono intrinsecamente non ordinate, quindi l'ordine in cui appaiono i mapping non ha importanza:

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

Puoi verificare se qualcosa è una mappa usando la map? predicato:

(map? {})
;;=> true

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

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

(map? nil)
;;=> false

(map? 42)
;;=> false

(map? :foo)
;;=> false

È possibile verificare se una mappa contiene una determinata chiave in "costante" utilizzando il contains? predicato:

(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

Puoi ottenere il valore associato a una chiave usando 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

Inoltre, le mappe stesse sono funzioni che accettano una chiave e restituiscono il valore associato a quella chiave:

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

Puoi trovare un'intera voce della mappa (chiave e valore insieme) come vettore a due elementi usando 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

È possibile estrarre la chiave o il valore da una voce della mappa utilizzando la key o val , rispettivamente:

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

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

Si noti che, sebbene tutte le voci della mappa Clojure siano vettori, non tutti i vettori sono voci della mappa. Se provi a chiamare la key o val su qualsiasi cosa che non è una voce della mappa, otterrai una ClassCastException :

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

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

Puoi verificare se qualcosa è una voce della map-entry? usando la voce della map-entry? predicato:

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

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

Puoi utilizzare assoc per ottenere una mappa che abbia tutte le stesse coppie chiave-valore di una mappa esistente, con una mappatura aggiunta o modificata:

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

Puoi usare dissoc per ottenere una mappa che abbia tutte le stesse coppie chiave-valore di una mappa esistente, con eventualmente una mappatura rimossa:

(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 restituisce il numero di mapping, in tempo costante:

(count {})
;;=> 0

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

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

Puoi ottenere una sequenza di tutte le voci in una mappa usando seq :

(seq {})
;;=> nil

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

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

Di nuovo, le mappe non sono ordinate, quindi l'ordinamento degli elementi in una sequenza che ottieni chiamando seq su una mappa non è definito.

È possibile ottenere una sequenza di soli i tasti o solo i valori in una mappa utilizzando keys o vals , rispettivamente:

(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 aggiunge una sintassi letterale per rappresentare in modo più conciso una mappa in cui le chiavi condividono lo stesso spazio dei nomi. Si noti che la mappa in entrambi i casi è identica (la mappa non "conosce" lo spazio dei nomi predefinito), questa è solo una comodità sintattica.

;; 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow