Recherche…


Destruction d'un vecteur

Voici comment vous pouvez déstructurer un vecteur:

(def my-vec [1 2 3])

Ensuite, par exemple dans un bloc let , vous pouvez extraire les valeurs du vecteur très succinctement comme suit:

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

Détruire une carte

Voici comment vous pouvez déstructurer une carte:

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

Ensuite, par exemple, dans un bloc let, vous pouvez extraire les valeurs de la carte très succinctement comme suit:

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

Notez que les valeurs extraites dans chaque mappage sont à gauche et les clés auxquelles elles sont associées sont à droite.

Si vous souhaitez déstructurer des valeurs vers des liaisons ayant les mêmes noms que les clés, vous pouvez utiliser ce raccourci:

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

Si vos clés sont des chaînes, vous pouvez utiliser presque la même structure:

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

Et de même pour les symboles:

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

Si vous souhaitez déstructurer une carte imbriquée, vous pouvez imbriquer les formes de liaison expliquées ci-dessus:

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

Destruction des éléments restants en une séquence

Disons que vous avez un vecteur comme ça:

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

Et vous voulez extraire les 3 premiers éléments et obtenir les éléments restants sous forme de séquence. Cela peut être fait comme suit:

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

Destructuration de vecteurs imbriqués

Vous pouvez déstructurer les vecteurs imbriqués:

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

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

Destruction d'une carte avec des valeurs par défaut

Parfois, vous voulez détruire la clé sous une carte qui pourrait ne pas être présente dans la carte, mais vous voulez une valeur par défaut pour la valeur déstructurée. Vous pouvez le faire de cette façon:

(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

Destruction des paramètres d'une fn

La destruction fonctionne dans de nombreux endroits, ainsi que dans la liste des paramètres d'une fn:

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

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

La destruction fonctionne également pour la construction & rest dans la liste des paramètres:

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

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

Conversion du reste d'une séquence en carte

La destruction vous permet également d’interpréter une séquence comme une carte:

(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

C'est utile pour définir des fonctions avec des paramètres nommés :

(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

Vue d'ensemble

La destruction vous permet d'extraire des données de divers objets dans des variables distinctes. Dans chaque exemple ci-dessous, chaque variable est affectée à sa propre chaîne ( a = "a" , b = "b" , & c.)

Type Exemple Valeur des data / commentaire
vec (let [[abc] data ...) ["a" "b" "c"]
vec imbriqué (let [[[ab] [cd]] data ...) [["a" "b"] ["c" "d"]]
map (let [{a :ab :bc :c} data ...) {:a "a" :b "b" :c "c"}
- alternative: (let [{:keys [abc]} data ...) Lorsque les variables sont nommées d'après les clés.

Conseils:

Destructuration et liaison au nom des clés

Parfois, lors de la déstructuration des cartes, vous souhaitez lier les valeurs déstructurées à leur nom de clé respectif. Selon la granularité de la structure de données, l'utilisation du schéma de déstructuration standard peut être un peu verbeux .

Disons que nous avons un enregistrement basé sur la carte comme ceci:

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

nous le déstructurions normalement comme ça:

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

ici, la structure des données est assez simple avec seulement 3 slots ( prénom, nom, pays ) mais imaginez la lourdeur si nous devions répéter tous les noms de clés deux fois pour une structure de données plus granulaire (avec bien plus de slots que 3) .

Au lieu de cela, une meilleure façon de gérer cela consiste à utiliser :keys (puisque nos clés sont des mots - clés ici) et à sélectionner le nom de la clé que nous aimerions lier ainsi:

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

La même logique intuitive s'applique à d'autres types de clés comme les symboles (en utilisant :syms ) et les anciennes chaînes simples (en utilisant :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"

Destructuration et attribution d'un nom à la valeur d'argument d'origine

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

(print-some-items [2 3])

Cet exemple imprime la sortie

2
3
[2 3]

L'argument est déstructuré et les éléments 2 et 3 sont affectés aux symboles a et b . L'argument d'origine, le vecteur entier [2 3] , est également affecté au symbole xs .



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow