clojure
Clojure destructuring
수색…
벡터 파괴하기
벡터를 디 컴포지션하는 방법은 다음과 같습니다.
(def my-vec [1 2 3])
그런 다음 예를 들어 let
블록 내에서 다음과 같이 벡터에서 값을 매우 간결하게 추출 할 수 있습니다.
(let [[x y] my-vec]
(println "first element:" x ", second element: " y))
;; first element: 1 , second element: 2
지도 파괴하기
다음은지도를 분리하는 방법입니다.
(def my-map {:a 1 :b 2 :c 3})
그런 다음 예를 들어, let 블록 내에서 다음과 같이지도에서 값을 매우 간결하게 추출 할 수 있습니다.
(let [{x :a y :c} my-map]
(println ":a val:" x ", :c val: " y))
;; :a val: 1 , :c val: 3
각 매핑에서 추출되는 값은 왼쪽에 있고 연관된 키는 오른쪽에 있습니다.
키와 같은 이름을 가진 바인딩에 값을 디 컴포지션하려면이 바로 가기를 사용할 수 있습니다.
(let [{:keys [a c]} my-map]
(println ":a val:" a ", :c val: " c))
;; :a val: 1 , :c val: 3
키가 문자열 인 경우 거의 동일한 구조를 사용할 수 있습니다.
(let [{:strs [foo bar]} {"foo" 1 "bar" 2}]
(println "FOO:" foo "BAR: " bar ))
;; FOO: 1 BAR: 2
심볼도 마찬가지입니다.
(let [{:syms [foo bar]} {'foo 1 'bar 2}]
(println "FOO:" foo "BAR:" bar))
;; FOO: 1 BAR: 2
중첩 된 맵을 제거하려는 경우 위에 설명 된 바인딩 양식을 중첩 할 수 있습니다.
(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]
나머지 원소를 시퀀스로 분해하기
다음과 같은 벡터가 있다고 가정 해 보겠습니다.
(def my-vec [1 2 3 4 5 6])
그리고 처음 세 요소를 추출하여 나머지 요소를 시퀀스로 가져 오려고합니다. 이 작업은 다음과 같이 수행 할 수 있습니다.
(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)
중첩 된 벡터 파괴
중첩 벡터를 제거 할 수 있습니다.
(def my-vec [[1 2] [3 4]])
(let [[[a b][c d]] my-vec]
(println a b c d))
;; 1 2 3 4
디폴트 값을 갖는 맵의 파괴
맵에 존재하지 않을 수도있는 맵 아래에서 키를 제거하려는 경우가 있지만 소멸 값의 기본값을 원할 때가 있습니다. 당신은 이렇게 할 수 있습니다 :
(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
fn의 params 분해하기
Destructurling은 여러 위치 에서뿐만 아니라 fn의 param 목록에서도 작동합니다.
(defn my-func [[_ a b]] (+ a b)) (my-func [1 2 3]) ;= 5 (my-func (range 5)) ;= 3
destructuring은 param 목록의 & rest
구조에서도 작동합니다.
(defn my-func2 [& [_ a b]] (+ a b)) (my-func2 1 2 3) ;= 5 (apply my-func2 (range 5)) ;= 3
시퀀스의 나머지 부분을지도로 변환
또한 Destructuring은 시퀀스를 맵으로 해석하는 기능을 제공합니다.
(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
명명 된 매개 변수를 사용 하여 함수를 정의 할 때 유용합니다.
(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
개요
Destructuring을 사용하면 다양한 오브젝트의 데이터를 별개의 변수로 추출 할 수 있습니다. 아래의 각 예에서 각 변수는 자체 문자열 ( a
= "a"
, b = "b"
및 & c)에 할당됩니다.
유형 | 예 | data / 코멘트의 가치 |
---|---|---|
vec | (let [[abc] data ...) | ["a" "b" "c"] |
중첩 된 vec | (let [[[ab] [cd]] data ...) | [["a" "b"] ["c" "d"]] |
map | (let [{a :ab :bc :c} data ...) | {:a "a" :b "b" :c "c"} |
- 대안 : | (let [{:keys [abc]} data ...) | 변수 이름이 키의 이름을 따를 때. |
팁 :
- 기본값은
:or
사용하여 제공 할 수 있습니다:or
그렇지 않으면 기본값은nil
- 사용
& rest
가게하는seq
에 여분의 값의rest
다른 여분의 값이 무시되고, - 일반적으로 유용한 기능은 함수 매개 변수를 사용하는 것입니다.
- 원하지 않는 부분을 던져 버릴 수있는 변수에 할당 할 수 있습니다 (일반적으로
_
).
Key의 이름에 대한 소멸 및 바인딩
때로는 맵을 소멸시킬 때 소멸 값을 각각의 키 이름에 바인딩하고 싶을 때가 있습니다. 데이터 구조의 세분성에 따라 표준 destructuring 체계를 사용하는 것은 약간 장황 할 수 있습니다.
예를 들어 다음과 같은지도 기반 레코드가 있다고 가정 해 봅시다.
(def john {:lastname "McCarthy" :firstname "John" :country "USA"})
우리는 일반적으로 다음과 같이 그것을 파기합니다 :
(let [{lastname :lastname firstname :firstname country :country} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
여기서는 데이터 구조가 3 개의 슬롯 ( 성, 성, 국가 )으로 매우 간단하지만 더 세분화 된 데이터 구조를 위해 모든 키 이름을 두 번 반복해야한다면 얼마나 귀찮은 지 상상해보십시오 .
대신, 이것을 처리하는 더 좋은 방법은 :keys
(우리의 키는 여기에있는 키워드 이기 때문에)와 bind하기를 원하는 키 이름을 선택하는 것입니다 :
(let [{:keys [firstname lastname country]} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
동일한 직관적 인 논리가 기호 ( :syms
) 및 일반 오래된 문자열 ( :strs
사용)과 같은 다른 키 유형에도 적용됩니다 :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"
원래의 인수 값을 파괴하고 이름을 지정합니다.
(defn print-some-items
[[a b :as xs]]
(println a)
(println b)
(println xs))
(print-some-items [2 3])
이 예제는 출력을 출력한다.
2
3
[2 3]
인수가 소멸되고 항목 2
와 3
이 기호 a
와 b
됩니다. 원래의 인수 인 전체 벡터 [2 3]
는 기호 xs
에도 할당됩니다.