Szukaj…


Niszczenie wektora

Oto jak możesz zniszczyć wektor:

(def my-vec [1 2 3])

Następnie, na przykład w bloku let , możesz bardzo zwięźle wyodrębnić wartości z wektora w następujący sposób:

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

Niszczenie mapy

Oto jak możesz zniszczyć mapę:

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

Następnie, na przykład, w bloku let możesz bardzo zwięźle wyodrębnić wartości z mapy w następujący sposób:

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

Zauważ, że wartości wyodrębniane w każdym odwzorowaniu znajdują się po lewej stronie, a klawisze, z którymi są powiązane, znajdują się po prawej stronie.

Jeśli chcesz zniszczyć wartości powiązań o takich samych nazwach jak klucze, możesz użyć tego skrótu:

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

Jeśli twoje klucze są łańcuchami, możesz użyć prawie takiej samej struktury:

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

Podobnie w przypadku symboli:

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

Jeśli chcesz zniszczyć zagnieżdżoną mapę, możesz zagnieździć formularze wiążące wyjaśnione powyżej:

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

Przekształcanie pozostałych elementów w sekwencję

Powiedzmy, że masz taki wektor:

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

I chcesz wyodrębnić pierwsze 3 elementy i uzyskać pozostałe elementy w sekwencji. Można to zrobić w następujący sposób:

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

Restrukturyzacja wektorów zagnieżdżonych

Możesz zniszczyć zagnieżdżone wektory:

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

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

Niszczenie mapy z wartościami domyślnymi

Czasami chcesz zniszczyć klucz pod mapą, która może nie być obecna na mapie, ale potrzebujesz domyślnej wartości zniszczonej wartości. Możesz to zrobić w ten sposób:

(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

Destrukturyzacja parametrów fn

Destructurling działa w wielu miejscach, a także na liście parametrów fn:

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

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

Destrukturyzacja działa również w przypadku konstrukcji & rest z listy parametrów:

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

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

Konwertowanie reszty sekwencji na mapę

Destrukturyzacja daje również możliwość interpretacji sekwencji jako mapy:

(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

Jest to przydatne do definiowania funkcji o nazwanych parametrach :

(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

Przegląd

Destrukturyzacja pozwala wyodrębnić dane z różnych obiektów do odrębnych zmiennych. W każdym z poniższych przykładów każda zmienna jest przypisana do własnego łańcucha ( a = "a" , b = "b" i c.)

Rodzaj Przykład Wartość data / komentarza
vec (let [[abc] data ...) ["a" "b" "c"]
zagnieżdżone vec (let [[[ab] [cd]] data ...) [["a" "b"] ["c" "d"]]
map (let [{a :ab :bc :c} data ...) {:a "a" :b "b" :c "c"}
- alternatywa: (let [{:keys [abc]} data ...) Kiedy zmienne są nazywane po kluczach.

Wskazówki:

Niszczenie i wiązanie z nazwą klucza

Czasami podczas mapowania destrukcji chciałbyś powiązać zniszczone wartości z ich odpowiednimi nazwami kluczy. W zależności od ziarnistości struktury danych użycie standardowego schematu destrukcji może być nieco szczegółowe .

Powiedzmy, że mamy zapis oparty na mapie:

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

normalnie byśmy to zniszczyli w ten sposób:

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

tutaj struktura danych jest dość prosta i ma tylko 3 miejsca ( imię, nazwisko, kraj ), ale wyobraź sobie, jak uciążliwe byłoby, gdybyśmy musieli powtórzyć wszystkie nazwy kluczy dwa razy, aby uzyskać bardziej szczegółową strukturę danych (mając znacznie więcej miejsc niż tylko 3) .

Zamiast tego lepszym sposobem radzenia sobie z tym jest użycie :keys (ponieważ nasze klucze są tutaj słowami kluczowymi ) i wybranie nazwy klucza, z którym chcielibyśmy się powiązać:

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

Ta sama intuicyjna logika dotyczy innych typów kluczy, takich jak symbole (using :syms ) i zwykłe stare ciągi znaków (using :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"

Restrukturyzacja i nadanie nazwy pierwotnej wartości argumentu

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

(print-some-items [2 3])

Ten przykład drukuje dane wyjściowe

2
3
[2 3]

Argument jest zniszczony, a pozycje 2 i 3 są przypisane do symboli a i b . Oryginalny argument, cały wektor [2 3] , jest również przypisany do symbolu xs .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow