サーチ…
ベクトルを破壊する
ベクトルの構造を解除する方法は次のとおりです。
(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])
最初の3つの要素を抽出し、残りの要素をシーケンスとして取得したいとします。これは次のようにして行うことができます。
(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のパラメータを破壊する
Destructurlingは、fnのparamリストと同様に、多くの場所で動作します。
(defn my-func [[_ a b]] (+ a b)) (my-func [1 2 3]) ;= 5 (my-func (range 5)) ;= 3
破壊はparamリストの& rest
構文のためにも機能します:
(defn my-func2 [& [_ a b]] (+ a b)) (my-func2 1 2 3) ;= 5 (apply my-func2 (range 5)) ;= 3
残りのシーケンスをマップに変換する
デストラクタリングでは、シーケンスをマップとして解釈することもできます。
(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
を使用して指定できます 。そうでない場合はデフォルトはnil
-
& rest
を使用して、余分な値のseq
をrest
値に格納します 。そうでない場合、余分な値は無視されます。 - 一般的で有用な破壊の使用は、関数のパラメータです
- 不要な部分をスローアウェイ変数に割り当てることができます(通常は
_
)
キーの名前を破壊してバインドする
場合によっては、マップの構造を解除するときに、構造化された値をそれぞれのキー名にバインドしたいことがあります。データ構造の細かさに応じて、 標準の構造化スキームを使用することは少し冗長かもしれません。
たとえば、次のようなマップベースのレコードがあります。
(def john {:lastname "McCarthy" :firstname "John" :country "USA"})
我々は通常次のようにそれを破棄する:
(let [{lastname :lastname firstname :firstname country :country} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
ここでは、データ構造は3つのスロット(名字、姓、国 )で非常に単純ですが、もっと細かいデータ構造(3よりも多くのスロットを持つ)ですべてのキー名を2回繰り返さなければならない場合、 。
代わりに、これを処理するより良い方法は:keys
(ここでキーはキーワードです)とバインドしたいキー名を選択することです:
(let [{:keys [firstname lastname country]} john]
(str firstname " " lastname ", " country))
;;"John McCarthy, USA"
同じ直感的なロジックが、 シンボル ( :syms
を使用)と普通の古い文字列 ( :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
割り当てられます。