我使用以下表达式来检索向量中最小数字的索引。但是,我想避免使用.indexOf
(出于效率原因和数字精度,尽管我猜数字会隐式转换为字符串)。
(.indexOf [1 2 3 4 0 5]
(reduce #(if (< %1 %2) %1 %2) [1 2 3 4 0 5] ))
是否可以使用reduce进行不同的操作?
答案 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