Ricerca…


Distruzione di un vettore

Ecco come puoi distruggere un vettore:

(def my-vec [1 2 3])

Quindi, ad esempio all'interno di un blocco let , è possibile estrarre i valori dal vettore in modo molto succinto come segue:

(let [[x y] my-vec]
 (println "first element:" x ", second element: " y))
;; first element: 1 , second element: 2

Distruzione di una mappa

Ecco come puoi distruggere una mappa:

(def my-map {:a 1 :b 2 :c 3})

Quindi, ad esempio, all'interno di un blocco let è possibile estrarre i valori dalla mappa in modo molto succinto come segue:

(let [{x :a y :c} my-map]
  (println ":a val:" x ", :c val: " y))
;; :a val: 1 , :c val: 3

Si noti che i valori estratti in ogni mappatura sono sulla sinistra e le chiavi a cui sono associati sono sulla destra.

Se vuoi distruggere i valori con i bind con lo stesso nome dei tasti puoi usare questa scorciatoia:

(let [{:keys [a c]} my-map]
  (println ":a val:" a ", :c val: " c))
;; :a val: 1 , :c val: 3

Se le tue chiavi sono stringhe puoi usare quasi la stessa struttura:

(let [{:strs [foo bar]} {"foo" 1 "bar" 2}]
  (println "FOO:" foo  "BAR: " bar ))
;; FOO: 1 BAR: 2

E allo stesso modo per i simboli:

(let [{:syms [foo bar]} {'foo 1 'bar 2}]
  (println "FOO:" foo "BAR:" bar))
;; FOO: 1 BAR: 2

Se si desidera distruggere una mappa nidificata, è possibile nidificare i moduli di associazione illustrati sopra:

(def data
  {:foo {:a 1
         :b 2}
   :bar {:a 10
         :b 20}})

(let [{{:keys [a b]} :foo
       {a2 :a b2 :b} :bar} data]
  [a b a2 b2])
;; => [1 2 10 20]

Distruzione di elementi rimanenti in una sequenza

Diciamo che hai un vettore come questo:

(def my-vec [1 2 3 4 5 6])

E vuoi estrarre i primi 3 elementi e ottenere gli elementi rimanenti come sequenza. Questo può essere fatto come segue:

(let [[x y z & remaining] my-vec]
 (println "first:" x ", second:" y "third:" z "rest:" remaining))
;= first: 1 , second: 2 third: 3 rest: (4 5 6)

Distruzione di vettori annidati

Puoi distruggere i vettori annidati:

(def my-vec [[1 2] [3 4]])

(let [[[a b][c d]] my-vec]
  (println a b c d))
;; 1 2 3 4

Distruzione di una mappa con valori predefiniti

A volte si desidera distruggere la chiave sotto una mappa che potrebbe non essere presente nella mappa, ma si desidera un valore predefinito per il valore destrutturato. Puoi farlo in questo modo:

(def my-map {:a 3 :b 4})
(let [{a :a
       b :b
       :keys [c d]
       :or {a 1
            c 2}} my-map]
  (println a b c d))
  ;= 3 4 2 nil

Param di destrutturazione di un fn

La destrutturazione funziona in molti posti, così come nella lista param di un fn:

(defn my-func [[_ a b]]
  (+ a b))

(my-func [1 2 3]) ;= 5
(my-func (range 5)) ;= 3

La destrutturazione funziona anche per il costrutto & rest nella lista param:

(defn my-func2 [& [_ a b]]
  (+ a b))

(my-func2 1 2 3) ;= 5
(apply my-func2 (range 5)) ;= 3

Convertire il resto di una sequenza in una mappa

La destrutturazione ti dà anche la possibilità di interpretare una sequenza come una mappa:

(def my-vec [:a 1 :b 2])
(def my-lst '("smthg else" :c 3 :d 4))

(let [[& {:keys [a b]}] my-vec
      [s & {:keys [c d]} my-lst]
  (+ a b c d)) ;= 10

È utile per definire funzioni con parametri denominati :

(defn my-func [a b & {:keys [c d] :or {c 3 d 4}}]
  (println a b c d))

(my-func 1 2) ;= 1 2 3 4
(my-func 3 4 :c 5 :d 6) ;= 3 4 5 6

Panoramica

La destrutturazione consente di estrarre dati da vari oggetti in variabili distinte. In ogni esempio di seguito, ogni variabile è assegnata alla propria stringa ( a = "a" , b = "b" , & c.)

genere Esempio Valore di data / commenti
vec (let [[abc] data ...) ["a" "b" "c"]
vec annidato (let [[[ab] [cd]] data ...) [["a" "b"] ["c" "d"]]
map (let [{a :ab :bc :c} data ...) {:a "a" :b "b" :c "c"}
- alternativa: (let [{:keys [abc]} data ...) Quando le variabili prendono il nome dalle chiavi.

Suggerimenti:

Distruzione e associazione al nome delle chiavi

A volte, quando si distruggono le mappe, si desidera associare i valori destrutturati al rispettivo nome della chiave. A seconda della granularità della struttura dei dati, l'utilizzo dello schema di destrutturazione standard può essere un po ' prolisso .

Diciamo, abbiamo un record basato sulla mappa in questo modo:

(def john {:lastname "McCarthy" :firstname "John" :country "USA"})

normalmente lo distruggeremo in questo modo:

(let [{lastname :lastname firstname :firstname country :country} john]
    (str firstname " " lastname ", " country))
;;"John McCarthy, USA"

qui, la struttura dei dati è piuttosto semplice con solo 3 slot ( nome, cognome, nazione ) ma immagina quanto sarebbe ingombrante se dovessimo ripetere due volte tutti i nomi dei tasti per una struttura dati più granulare (avendo più slot di appena 3) .

Invece, un modo migliore per gestirlo è usando :keys (dato che le nostre chiavi sono parole chiave qui) e selezionando il nome della chiave che vorremmo associare a like like:

(let [{:keys [firstname lastname country]} john]
    (str firstname " " lastname ", " country))
;;"John McCarthy, USA"

La stessa logica intuitiva vale per altri tipi di chiavi come i simboli (usando :syms ) e le semplici stringhe vecchie (usando :strs )

;; using strings as keys
(def john {"lastname" "McCarthy" "firstname" "John" "country" "USA"})
;;#'user/john

;; destructuring string-keyed map
(let [{:strs [lastname firstname country]} john]
    (str firstname " " lastname ", " country))
;;"John McCarthy, USA"

;; using symbols as keys
(def john {'lastname "McCarthy" 'firstname "John" 'country "USA"})

;; destructuring symbol-keyed map
(let [{:syms [lastname firstname country]} john]
    (str firstname " " lastname ", " country))
;;"John McCarthy, USA"

Distruzione e dare un nome al valore dell'argomento originale

(defn print-some-items 
   [[a b :as xs]]
  (println a)
  (println b)
  (println xs))

(print-some-items [2 3])

Questo esempio stampa l'output

2
3
[2 3]

L'argomento è destrutturato e gli elementi 2 e 3 sono assegnati ai simboli a e b . L'argomento originale, l'intero vettore [2 3] , viene anche assegnato al simbolo xs .



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow