我使用了下面的表达式来检索一个向量中最小的数字的索引。然而,我想避免使用 .indexOf
(出于效率的考虑,也许还有数字的精度,虽然我猜数字是隐式转换为字符串的)。
(.indexOf [1 2 3 4 0 5]
(reduce #(if (< %1 %2) %1 %2) [1 2 3 4 0 5] ))
能否用reduce来做不同的事情?
user=> (first (apply min-key second (map-indexed vector [1 2 4 0 5])))3
如果你想高效地完成这个任务,我建议使用 looprecur,也许像下面这样。
(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))))
我们的想法是在整个向量上进行迭代, 跟踪每个点的最小值和最小值的索引.
你也可以使用 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
实际上是一个三元素向量,包括了 最小值,其 指数和一个索引跟踪器(这并不重要),分别。并且它对集合进行一次遍历。
提供给 reduce
基本上是收藏的第一要素。
我知道这个问题已经很老了,但为了后人,还是在这里提出来。