我试图在向量中找到特定函数求值为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
答案 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]