2010/02/26

Clojureのcontains?関数

contains?関数はコレクションにキーが存在するかどうかを確かめるために使う。
> (contains? {:h "hoge" :f "fuga"} :h)
true
だから下のコードのように値の存在を確かめることはできない。
> (contains? ["hoge" "fuga"] "hoge") ; 値を指定
false
> (contains? ["hoge" "fuga"] 0) ; キーを指定
true
値の存在を確かめるにはsome関数を使うのが良さそう。
> (some #(= "hoge" %) ["hoge" "fuga"])
true
> (some #(= "hoge" %) (vals {:h "hoge" :f "fuga"}))
true
ただこの場合、存在しなかったときはfalseではなくnilが返ってくる。
> (some #(= "durarara" %) (vals {:h "hoge" :f "fuga"}))
nil
(contains? ["x","y"] "x") => false; Works as designed. This design confuses me. #clojure #novice
というTweetを見かけたので書いてみました。

追記(2010/02/27 00:06):
(some #(= x %) coll)の代わりになるincludes?という関数がclojure.contrib.seq-utilsに用意されていた。こっちのほうがスマートかも。
> (use '[clojure.contrib.seq-utils :only (includes?)])
nil
> (includes? ["hoge" "fuga"] "hoge")
true
> (includes? (vals {:h "hoge" :f "fuga"}) "hoge")
true
> (includes? (vals {:h "hoge" :f "fuga"}) "durarara")
false

追記(2010/02/27 00:38):
動作環境は、Clojure 1.1.0とclojure-contrib 1.1.0です。

0 件のコメント:

コメントを投稿