返回满足函数返回true的地图/列表/序列中的第一项
我正在寻找一个函数,返回一个序列中的第一个元素,将fn评估为true。 例如:
(first-map (fn [x] (= x 1)) '(3 4 1)) 上面的假function应该返回1(列表中的最后一个元素)。 在Clojure中有这样的东西吗?
 user=> (defn find-first [f coll] (first (filter f coll))) #'user/find-first user=> (find-first #(= % 1) [3 4 1]) 1 
  编辑:并发。  :)不,它不适用于整个名单。 由于filter懒惰,只能到达第一个匹配的元素。 
就你而言,这个成语是
 (some #{1} [1 2 3 4]) 
 工作原理:#{1}是一组字面值。 一个集合也是一个函数,如果arg存在于集合中则评估其arg,否则为零。 任何set元素都是一个“真值”(好吧,除了布尔值假,但这是一个罕见的集合)。  some返回谓词的返回值,这个谓词是针对第一个集合成员评估的,结果是真实的。 
我尝试了这个线程中提到的几个方法(JDK 8和Clojure 1.7),并做了一些基准testing:
 repl> (defn find-first [f coll] (first (filter f coll))) #'cenx.parker.strategies.vzw.repl/find-first repl> (time (find-first #(= % 50000000) (range))) "Elapsed time: 5799.41122 msecs" 50000000 repl> (time (some #{50000000} (range))) "Elapsed time: 4386.256124 msecs" 50000000 repl> (time (reduce #(when (= %2 50000000) (reduced %2)) nil (range))) "Elapsed time: 993.267553 msecs" 50000000 
 结果表明, reduce方式可能是最有效的解决scheme,如clojure 1.7。 
 我认为some是这个工作最好的工具: 
 (some #(if (= % 1) %) '(3 4 1)) 
 使用drop-while代替filter应该解决分块序列的f “over-application”问题: 
 (defn find-first [f coll] (first (drop-while (complement f) coll))) ;;=> #'user/find-first (find-first #(= % 1) [3 4 1]) ;;=> 1