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

在Clojure中查找与谓词匹配的元素的索引?,clojure,Clojure,使用Clojure,如何在该向量中找到第一个具有正值的索引[-1 0 3 7 9] 我知道你可以通过first和filter非常优雅地获得某些东西的第一个结果: (first (filter pos? [-1 0 99 100 101])) 此代码返回值99。我想要的答案是索引2 (defn pred-idx [pred [idx hist] cur] (if (pred cur) [(inc idx) (conj hist idx)] [(inc idx) hist]))

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

我知道你可以通过
first
filter
非常优雅地获得某些东西的第一个结果:

(first (filter pos? [-1 0 99 100 101]))
此代码返回值
99
。我想要的答案是索引
2

(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
不确定这是否更好,但它有效。我认为这会迫使对整个序列进行评估,如果你需要所有的索引,那会更好。正确的做法可能是以某种方式将其转换为一个懒惰的序列,但我今晚已经完成了。

试试以下方法:

(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])
它返回满足谓词的第一个元素的从零开始的索引(
在本例中是pos?
),如果没有元素与谓词匹配,则返回-1

(defn first-pos [x] 
  (loop [arr x n 0]
     (if (pos? (first arr))
     n
     (recur (next arr) (inc n)))))
这是一个使用函数式编程强大的尾部递归的好例子

使用可以获得满足谓词的索引序列:

(defn indices [pred coll]
   (keep-indexed #(when (pred %2) %1) coll))
使用这个简单的函数,您将解决表达式的问题

user=> (first (indices pos? [-1 0 99 100 101]))
2
注意,由于
保持索引
(和
索引
)的懒散性,不需要实现整个序列,因此不会执行额外的计算

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

Map可以获取一个或多个集合并返回一个列表,在Map上设置条件并过滤为零。

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

(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

看这里:我的问题完全不同。我编辑了我的标题来反映这一点。我想要一些能够处理我的例子的东西。找到一个集合中第一个正值的索引。我把它粘在脑子里,所以一直在尝试。但这不是一个理想的解决方案。如果显式传递
nil
,则此函数将只返回-1,因为
(rest x)
对于任何
x
,都不会是nil。在测试集合是否为nil之前,应该先调用集合上的
seq
。另外,
[pred coll]
的参数顺序比
[coll pred]
-cf.
map
filter
更友好。这是可行的(根据amalloy的建议),但使用keep index的版本要简单得多。在这里,我根据@amalloy的评论编辑了它。来自一个计划背景,这是奇怪的零()在ClojureIt中,如果列表中没有正元素,则失败并出现
NullPointerException
;OP还要求匹配任意谓词,而不仅仅是
pos?
这非常有效。(当我深入研究时,我注意到
keep indexed
包括非nil(其中包括
false
)结果。我不知道这样做的理由。)