Zoeken…


Een vector vernietigen

Hier is hoe je een vector kunt vernietigen:

(def my-vec [1 2 3])

Dan, bijvoorbeeld binnen een let blok, kunt u waarden als volgt uit de vector halen als volgt:

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

Een kaart vernietigen

U kunt als volgt een kaart vernietigen:

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

Vervolgens kunt u bijvoorbeeld binnen een let-blok heel bondig waarden als volgt uit de kaart halen:

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

Merk op dat de waarden die in elke afbeelding worden geëxtraheerd zich aan de linkerkant bevinden en de toetsen waaraan ze zijn gekoppeld, zich aan de rechterkant bevinden.

Als u waarden wilt vernietigen voor bindingen met dezelfde namen als de toetsen, kunt u deze sneltoets gebruiken:

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

Als uw sleutels tekenreeksen zijn, kunt u bijna dezelfde structuur gebruiken:

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

En evenzo voor symbolen:

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

Als u een geneste kaart wilt vernietigen, kunt u bindende formulieren nesten zoals hierboven uitgelegd:

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

Resterende elementen in een reeks vernietigen

Laten we zeggen dat je zo'n vector hebt:

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

En u wilt de eerste 3 elementen extraheren en de resterende elementen als een reeks krijgen. Dit kan als volgt worden gedaan:

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

Geneste vectoren vernietigen

U kunt geneste vectoren vernietigen:

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

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

Een kaart met standaardwaarden vernietigen

Soms wilt u de sleutel vernietigen onder een kaart die mogelijk niet aanwezig is op de kaart, maar wilt u een standaardwaarde voor de vernietigde waarde. Je kunt dat op deze manier doen:

(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

Vernietiging van params van een fn

Destructurling werkt op veel plaatsen, evenals in de param-lijst van een fn:

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

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

Destructurering werkt ook voor de & rest constructie in de param-lijst:

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

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

De rest van een reeks converteren naar een kaart

Destructurering geeft je ook de mogelijkheid om een reeks als een kaart te interpreteren:

(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

Het is handig voor het definiëren van functies met benoemde parameters :

(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

Overzicht

Met destructurering kunt u gegevens uit verschillende objecten extraheren in verschillende variabelen. In elk onderstaande voorbeeld wordt elke variabele toegewezen aan zijn eigen string ( a = "a" , b = "b" , & c.)

Type Voorbeeld Waarde van data / opmerking
vec (let [[abc] data ...) ["a" "b" "c"]
genest vec (let [[[ab] [cd]] data ...) [["a" "b"] ["c" "d"]]
map (let [{a :ab :bc :c} data ...) {:a "a" :b "b" :c "c"}
- alternatief: (let [{:keys [abc]} data ...) Wanneer variabelen naar de toetsen worden genoemd.

Tips:

Vernietiging en binding aan de naam van de sleutels

Soms wilt u bij het vernietigen van kaarten de vernietigde waarden binden aan hun respectievelijke sleutelnaam. Afhankelijk van de granulariteit van de gegevensstructuur, kan het gebruik van het standaardvernietigingsschema een beetje uitgebreid zijn .

Laten we zeggen, we hebben een kaartgebaseerd record als volgt:

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

we zouden het normaal gesproken zo vernietigen:

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

hier is de gegevensstructuur vrij eenvoudig met slechts 3 slots ( voornaam, achternaam, land ), maar stel je voor hoe omslachtig het zou zijn als we alle sleutelnamen twee keer moesten herhalen voor een meer gedetailleerde gegevensstructuur (met veel meer slots dan slechts 3) .

In plaats daarvan is een betere manier om dit te doen het gebruik van :keys (omdat onze sleutels hier sleutelwoorden zijn) en het selecteren van de sleutelnaam waaraan we willen binden, dus:

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

Dezelfde intuïtieve logica is van toepassing op andere sleuteltypen zoals symbolen (met :syms ) en gewone oude tekenreeksen (met :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"

Destructureren en een naam geven aan de oorspronkelijke argumentwaarde

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

(print-some-items [2 3])

In dit voorbeeld wordt de uitvoer afgedrukt

2
3
[2 3]

Het argument is vernietigd en de items 2 en 3 zijn toegewezen aan de symbolen a en b . Het oorspronkelijke argument, de gehele vector [2 3] , wordt ook toegewezen aan het symbool xs .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow