Clojureを学ぶ 4clojure編 3
以前、ちょっとだけかじった事があった Clojure を、もういっかい勉強中。
4clojureは以前やったことはあったけど、すっかり忘れているので、最初からやり直してます。
今回やったのは、26問目~31問目。これで、一番簡単なレベル「Elementary」は完了。
このあたりになると、僕の知識では1問ずつ調べながら理解して進んでいく感じになります。
- A nil key
- For the win
- Logical falsity and truth
- Intro to Destructuring
- Subset and Superset
- Map Defaults
メモ
「A nil key」
キーとマップを指定し、マップにそのキーを持つエントリが含まれ、その値が nil である場合に真を返す関数を記述せよ
(true? (__ :a {:a nil :b 2}))
(false? (__ :b {:a nil :b 2}))
(false? (__ :c {:a nil :b 2}))
;;自分の回答
#(if (contains? %2 %1)
(nil? (%1 %2))
false)
;
;;他の人の回答
;
;and はショートサーキット
;mapにkeyが含まれないとfalse
;含まれていた場合、値がnilならtrue
#(and (contains? %2 %1) (nil? (%1 %2)))
;
;get の第3引数は、not-foundの値
;Clojureで偽になるのは、falseとnilのみ
#(not (%2 %1 true))
#(nil? (get %2 %1 true))
;
;not-foundの時にkeyが返る。コードゴルフ対策?
#(nil? (%2 % %))
「For the win」
これらの式を読んで、それぞれがどのようにして同じ結果を得るかを試してみてください。
;x = [0 ... 39] で、xを4で割った余りが1のものだけ抽出
;なので、1,5,9,…37
(for [x (range 40)
:when (= 1 (rem x 4))]
x)
;
;(iterate f x) は x, (f x), (f (f x))… を返す
;xは、0,4,8,12 …
;zは、1,5,9,13 …で40未満
(for [x (iterate #(+ 4 %) 0)
:let [z (inc x)]
:while (< z 40)]
z)
;
;(partition n coll) は、colをn個ずつに分割した値を返す
; (partition 2 (range 20))
; => ((0 1) (2 3) (4 5) (6 7) (8 9) (10 11) (12 13) (14 15) (16 17) (18 19))
;x,yには,0と1、2と3、4と5 …が入り、それぞれを足す
(for [[x y] (partition 2 (range 20))]
(+ x y))
「Map Defaults」
デフォルト値と一連のキーを取り、マップを構築する関数を書いてください。
(= (__ 0 [:a :b :c]) {:a 0 :b 0 :c 0})
(= (__ "x" [1 2 3]) {1 "x" 2 "x" 3 "x"})
(= (__ [:a :b] [:foo :bar]) {:foo [:a :b] :bar [:a :b]})
これは、内容的にElementaryじゃなく、Easyな気がします。
;;自分の回答
#(apply conj (for [k %2] (hash-map k %1)))
;
;;他の人の回答
;zipmap キーのコレクションと値のコレクションを引数にとって、マップを返す
#(zipmap %2 (repeat %1))
;
;(assoc {} :k1 1 :k2 2) => {:k1 1 :k2 2}
;(interleave [:a :b :c] [1 2 3]) => (:a 1 :b 2 :c 3)
#(apply assoc {}
(interleave %2 (repeat %1)))
;
;(into {} [[:k1 1] [:k2 2]]) => {:k1 1, :k2 2}
(fn [v ks]
(into {} (map #(vector % v) ks)))
ディスカッション
コメント一覧
まだ、コメントがありません