如何在Clojure中找到此向量的最小成员的索引?

时间:2012-01-11 07:40:57

标签: clojure reduce

我使用以下表达式来检索向量中最小数字的索引。但是,我想避免使用.indexOf(出于效率原因和数字精度,尽管我猜数字会隐式转换为字符串)。

(.indexOf [1 2 3 4 0 5]
  (reduce #(if (< %1 %2) %1 %2) [1 2 3 4 0 5] ))

是否可以使用reduce进行不同的操作?

4 个答案:

答案 0 :(得分:14)

user=> (first (apply min-key second (map-indexed vector [1 2 4 0 5])))
3

答案 1 :(得分:4)

如果您想有效地执行此操作,我建议使用loop / recur,可能类似于以下内容:

(defn min-index [v] 
  (let [length (count v)]
    (loop [minimum (v 0)
           min-index 0
           i 1]
      (if (< i length)
        (let [value (v i)]
          (if (< value minimum)
            (recur value i (inc i))
            (recur minimum min-index (inc i))))
        min-index))))

这个想法是迭代整个向量,跟踪到目前为止在每个点找到的最小值的最小值和索引。

答案 2 :(得分:1)

您也可以使用true

reduce

(def v [1 2 3 4 0 5]) (second (reduce (fn [[curr-min min-idx curr-idx] val] (if (< val curr-min) [val curr-idx (inc curr-idx)] [curr-min min-idx (inc curr-idx)])) [(first v) 0 0] v)) ;; => 4 的结果实际上是一个三元素向量,由最小值,其索引和索引跟踪器组成(这并不重要), 分别。并且遍历集合一次。

提供给reduce的初始值基本上是集合的第一个元素。

我知道这个问题很旧,但这是为了后代的缘故。

答案 3 :(得分:1)

跟进@Alex Taggart 的回答,使用 thread-last macro

user=> (->> [1 2 4 0 5]
  (map-indexed vector)   ; [[0 1] [1 2] [2 4] [3 0] [4 5]]
  (apply min-key second) ; [3 0]
  first)
3