【问题标题】:Reduce in Clojure在 Clojure 中减少
【发布时间】:2014-07-29 22:41:10
【问题描述】:

有人可以解释一下如何评估以下匿名函数吗?

(defn min-by [f coll] 
  (when (seq coll)
    (reduce (fn [min this]
        (if (> (f min) (f this)) this min))
      coll)))

(min-by :cost [{:cost 100} {:cost 36} {:cost 9}])
;=> {:cost 9}

我不明白minthis 的论点从何而来。似乎 coll 可能正在被隐式解构。

我怎样才能更好地理解这个函数在做什么?

【问题讨论】:

  • 另外,在这种特殊情况下,您最好使用内置的 clojure.core 函数 min-key 并将其应用于序列。
  • 正如你现在所看到的,克里斯,这并不是关于匿名函数的问题;这是一个关于reduce 的问题。 Arthur Ulfeldt 的回答非常好。您可能需要考虑编辑标题,以便将来人们在搜索类似信息时更容易找到您的问题和他的答案(以及任何其他答案)。

标签: clojure


【解决方案1】:

Reduce 需要一个函数作为它的第一个参数。这个函数有两个参数,第一个参数是“迄今为止的结果”,第二个参数是“用来改变它的数据”。在上面的例子中,reduce 正在接受一个函数,该函数接收迄今为止发现的最小的东西,以及与之比较的下一个元素。然后它决定其中哪个更小,并将其保留为迄今为止的结果。

(defn min-by [f   ;; this if a function that will be passed the smallest value 
                  ;; yet found and called again with the current value. 
                  ;; the result of these two calls will decide which is the min.
              coll] 
  (when (seq coll)
    (reduce 

      ;; first arg to reduce: a function to add something to the result

      ;; this function will be called once for each of the elements in the
      ;; collection passed as the second argument
      (fn [min     ; the result thus far 
           this]   ; the next element to include in the result

        ;; here we decide which is smaller by passing each to the function f
        ;; that was passed to min-by and compare is results for each of them.
        (if (> (f min) (f this)) this min))

      ;; second arg to reduce: the collection to work on

      ;; each element in this collection will be one of the values of
      ;; the "this" argument to the function above
      coll)))

这两个中间还有一个可选参数,用于指定结果的初始值。如果您省略此可选参数,如上例所示,则前两个参数用于生成结果中的第一个值。所以归约函数的调用次数实际上比输入集合中的元素数少一倍。

user> (defn print+ [& numbers] (println "called print+") (apply + numbers))
#'builder.upload/print+
user> (reduce print+ [1 2 3])
called print+
called print+
6
user> (reduce print+ 0 [1 2 3])
called print+
called print+
called print+
6

【讨论】:

    猜你喜欢
    • 2018-10-29
    • 2020-03-25
    • 1970-01-01
    • 2016-03-26
    • 2011-03-10
    • 2014-09-06
    • 1970-01-01
    • 2019-07-31
    • 2013-06-06
    相关资源
    最近更新 更多