Buscar..


Destructurando un vector

Así es como puedes destruir un vector:

(def my-vec [1 2 3])

Entonces, por ejemplo dentro de un let bloque, puede extraer los valores del vector de manera muy sucinta de la siguiente manera:

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

Destructurando un mapa

Así es como puedes destruir un mapa:

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

Luego, por ejemplo, dentro de un bloque Let puede extraer valores del mapa de manera muy sucinta de la siguiente manera:

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

Observe que los valores que se extraen en cada asignación están a la izquierda y las claves con las que están asociadas están a la derecha.

Si desea destruir valores en enlaces con los mismos nombres que las teclas, puede utilizar este acceso directo:

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

Si sus claves son cadenas, puede usar casi la misma estructura:

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

Y de manera similar para los símbolos:

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

Si desea destruir un mapa anidado, puede anidar los formularios de enlace explicados anteriormente:

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

Destrucción de los elementos restantes en una secuencia.

Digamos que tienes un vector así:

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

Y desea extraer los primeros 3 elementos y obtener los elementos restantes como una secuencia. Esto puede hacerse de la siguiente manera:

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

Destructurando vectores anidados

Puedes desestructurar vectores anidados:

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

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

Destrucción de un mapa con valores por defecto.

A veces desea destruir la clave debajo de un mapa que puede no estar presente en el mapa, pero desea un valor predeterminado para el valor desestructurado. Puedes hacerlo de esta manera:

(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

Destructurar params de un fn.

La destrucción se realiza en muchos lugares, así como en la lista de parámetros de una fn:

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

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

La destrucción también funciona para la construcción & rest en la lista de parámetros:

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

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

Convertir el resto de una secuencia en un mapa.

La destrucción también te da la capacidad de interpretar una secuencia como un mapa:

(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

Es útil para definir funciones con parámetros nombrados :

(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

Visión general

La destrucción le permite extraer datos de varios objetos en distintas variables. En cada ejemplo a continuación, cada variable se asigna a su propia cadena ( a = "a" , b = "b" , & c.)

Tipo Ejemplo Valor de los data / comentario
vec (let [[abc] data ...) ["a" "b" "c"]
vec anidado (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 ...) Cuando las variables llevan el nombre de las claves.

Consejos:

Destrucción y enlace al nombre de las llaves.

A veces, al desestructurar mapas, le gustaría vincular los valores desestructurados a su respectivo nombre de clave. Dependiendo de la granularidad de la estructura de datos, el uso del esquema de desestructuración estándar puede ser un poco detallado .

Digamos, tenemos un registro basado en el mapa como tal:

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

Normalmente lo destruiríamos así:

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

aquí, la estructura de datos es bastante simple con solo 3 espacios (primer nombre , apellido, país ), pero imagínese lo engorroso que sería si tuviéramos que repetir todos los nombres clave dos veces para obtener una estructura de datos más granular (con mucho más espacio que solo 3) .

En su lugar, una mejor manera de manejar esto es mediante :keys (ya que nuestras claves son palabras clave aquí) y seleccionando el nombre de la clave que nos gustaría vincular como así:

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

La misma lógica intuitiva se aplica a otros tipos de claves, como símbolos (con :syms ) y cadenas simples y sin formato (con :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"

Destrucción y nombre del argumento original.

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

(print-some-items [2 3])

Este ejemplo imprime la salida.

2
3
[2 3]

El argumento está desestructurado y los elementos 2 y 3 están asignados a los símbolos a y b . El argumento original, el vector completo [2 3] , también se asigna al símbolo xs .



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow