【发布时间】:2012-02-07 14:27:25
【问题描述】:
我使用以下表达式来检索向量中最小数字的索引。但是,我想避免使用.indexOf(出于效率原因和可能的数字精度,尽管我猜这些数字被隐式转换为字符串)。
(.indexOf [1 2 3 4 0 5]
(reduce #(if (< %1 %2) %1 %2) [1 2 3 4 0 5] ))
是否可以使用 reduce 来做不同的事情?
【问题讨论】:
我使用以下表达式来检索向量中最小数字的索引。但是,我想避免使用.indexOf(出于效率原因和可能的数字精度,尽管我猜这些数字被隐式转换为字符串)。
(.indexOf [1 2 3 4 0 5]
(reduce #(if (< %1 %2) %1 %2) [1 2 3 4 0 5] ))
是否可以使用 reduce 来做不同的事情?
【问题讨论】:
【讨论】:
如果您想有效地执行此操作,我建议使用循环/递归,可能类似于以下内容:
(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的初始值基本上是集合的第一个元素。
我知道这个问题已经过时了,但它是为了后代的缘故。
【讨论】:
跟进@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
【讨论】: