【问题标题】:How can I find the index of the smallest member of this vector in Clojure?如何在 Clojure 中找到该向量的最小成员的索引?
【发布时间】: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 来做不同的事情?

【问题讨论】:

    标签: clojure reduce


    【解决方案1】:
    user=> (first (apply min-key second (map-indexed vector [1 2 4 0 5]))) 3

    【讨论】:

    【解决方案2】:

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

    (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))))
    

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

    【讨论】:

    • 您是否有理由选择不使其对空输入具有鲁棒性?也许只是简洁?
    【解决方案3】:

    你也可以使用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的初始值基本上是集合的第一个元素。

    我知道这个问题已经过时了,但它是为了后代的缘故。

    【讨论】:

      【解决方案4】:

      跟进@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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-17
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        • 1970-01-01
        • 2011-06-17
        相关资源
        最近更新 更多