Clojure:找到函数求值为true的所有向量

时间:2014-09-01 01:03:13

标签: clojure

我试图在向量中找到特定函数求值为true的所有元素。我失败的尝试在下面。想法?

(defn find-matches [match-fn elements]
  (map-indexed 
    (fn [idx elem] 
      (if (= true (apply match-fn elem))
      [idx elem])
  elements))

(find-matches even? [1 2 3 4]) ; -> Arity Exception Wrong number of args (1) passed to: core$map-indexed clojure.lang.AFn.throwArity

3 个答案:

答案 0 :(得分:4)

听起来像filter

(def my-vec [1 2 5 9 10 15 22])
(filter even? my-vec)
=> (2 10 22)

如果您想要索引:

(for [[idx elem] (map vector (range) my-vec)
      :when (even? elem)]
  idx)
=> (1 4 6)

或两者:

(filter (comp even? second) (map vector (range) my-vec))
=>  ([1 2] [4 10] [6 22])

答案 1 :(得分:3)

您错过了fn调用的最后一个帖子。

此外,仅适用于集合,只需对单个项目使用该功能。

user> 
(defn find-matches [match-fn elements]
  (map-indexed 
    (fn [idx elem] 
      (if (= true (match-fn elem))
      [idx elem]))
    elements))

#'user/find-matches
user> (find-matches even? [1 2 3 4])
(nil [1 2] nil [3 4])

最后,我切换到保持索引,以便我们可以忽略nil元素,并使用在测试中使用任何非假值的一般clojure约定(因此我们不需要{{1只有x才足够。)

(= true x)

答案 2 :(得分:1)

结果是一系列数字。我们可以通过将不需要的条目映射到nil然后将其过滤掉来删除它们。

(defn find-matches [pred coll]
  (filter identity (map-indexed #(when (pred %2) %1) coll)))

任何值,但非负整数将作为black spot,但是nil之类的假值会使过滤变得微不足道。

例如,

(find-matches
  #(.startsWith % "b")
  (clojure.string/split "It's a braw bricht moonlicht nicht the nicht" #" "))
;(2 3)

结果是懒惰的,所以它可以处理无限序列:

(take 10 (find-matches even? (iterate inc 43)))
;(1 3 5 7 9 11 13 15 17 19)

如果要将整个有限结果转储到向量中,可以将其包装在vec中:

(vec (find-matches even? [1 2 3 4]))
;[1 3]