我曾使用下面这个表达式来获取向量中最小数字的索引。然而,出于效率和数字精度的考虑,我想避免使用.indexOf
(尽管我猜测数字会被隐式转换为字符串)。
(.indexOf [1 2 3 4 0 5]
(reduce #(if (< %1 %2) %1 %2) [1 2 3 4 0 5] ))
使用reduce是否可以以不同的方式完成它?
用户=> (第一个 (应用最小键值 函数 第二个 (映射索引化的向量 [1 2 4 0 5]))) 3
(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
< p > reduce
的结果实际上是一个三元向量,包括最小值、它的索引和一个索引跟踪器(不重要),并且它只遍历集合一次。
reduce
提供的初始值基本上是集合的第一个元素。
我知道这个问题很旧,但它在这里是为了纪念。
接下来是@Alex Taggart的回答,使用thread-last宏:
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