在Clojure中查找与谓词匹配的元素的索引?

时间:2011-12-27 04:54:08

标签: clojure

使用Clojure,如何在此向量[-1 0 3 7 9]中找到具有正值的第一个索引?

我知道您可以通过firstfilter获得优雅的第一个结果:

(first (filter pos? [-1 0 99 100 101]))

此代码返回值99。我想要的答案是索引,2

5 个答案:

答案 0 :(得分:40)

使用keep-indexed,您可以获得满足谓词的索引序列:

(defn indices [pred coll]
   (keep-indexed #(when (pred %2) %1) coll))

使用这个简单的功能,您将使用表达式

解决您的问题
user=> (first (indices pos? [-1 0 99 100 101]))
2

请注意,由于keep-indexed(和indices)的惰性,不需要实现整个序列,因此不会执行无关的计算。

答案 1 :(得分:1)

(defn pred-idx [pred [idx hist] cur]
  (if (pred cur)
    [(inc idx) (conj hist idx)]
    [(inc idx) hist]))

(defn idx-filter [pred col]
  (second (reduce (partial pred-idx pred) [0 []] col)))

(first (idx-filter pos? [-1 0 99 100 101]))
2

不确定这是否更好,但确实有效。我认为它会强制评估整个序列,如果你需要所有更好的指数。正确的做法可能是以某种方式把它变成一个懒惰的序列,但我已经完成了晚上。

答案 2 :(得分:1)

(first (filter #(not (nil? %)) (map #(when (pos? %1) %2) [-1 1 0 99 100 101] (range))))

Map可以获取一个或多个集合并返回一个列表,将条件放在地图上,并过滤nil。

答案 3 :(得分:0)

试试这个:

(defn first-index
  ([pred coll] (first-index coll pred 0))
  ([pred coll idx]
    (cond (= coll '()) -1
          (pred (first coll)) idx
          :else (recur pred (rest coll) (inc idx)))))

并像这样使用它:

(defn is-pos? [x]
  (> x 0))

(first-index is-pos? [-1 0 3 7 9])

它返回满足谓词的第一个元素的从零开始的索引(示例中为is-pos?),如果没有元素与谓词匹配,则返回-1。

答案 4 :(得分:0)

我参加聚会有点晚了,但是我更喜欢:

(defn index-of-pred
  [pred coll]
  (ffirst (filter (comp pred second) (map-indexed list coll))))

;; example usage
(index-of-pred pos? [-1 -2 -5 0 3 4 1 -100])
;=> 4