【问题标题】:Clojure: anonymous function with reduceClojure:带有reduce的匿名函数
【发布时间】:2017-07-18 02:50:03
【问题描述】:

我是 clojure 新手,在 clojure 文档中注意到了这个示例。

(reduce (fn [m [k v]] (assoc m v k)) {}{:b 2 :a 1 :c 3})

输出: ;;=> {2 :b, 1 :a, 3 :c}

谁能解释一下代码背后的逻辑?

【问题讨论】:

  • 你认为这意味着什么?您遇到了哪些问题?
  • {}{:b 2 :a 1 :c 3}
  • @user1702169 像这样将这两张地图“粘合”在一起并没有真正的帮助(除非您正在打代码打高尔夫球)。把它写成{} {...},很明显,这是两个不同的东西。

标签: clojure


【解决方案1】:

reduce 将函数应用于累加器和序列中的每个元素,构建最终结果。 ClojureDocs 将the signature for reduce 提供为(reduce f coll)(reduce f val coll)。您的示例具有后一个签名,其元素匹配如下:

  • f :应用于每个条目的函数,(fn [m [k v]] ...
  • val :初始累加器,{}
  • coll:要操作的集合,{:b 2 :a 1 :c 3}

请注意,reduce 调用的第二个和第三个参数之间没有分隔符(即空格)。 Clojure 不需要。

然后,查看内部匿名函数:(fn [m [k v]] (assoc m v k))。第一个参数m 是累加器的当前值,在reduce 开始时是{}Destructuring syntax 用于第二个参数,即要处理的当前值,即映射条目。映射条目被解构为它的键k 和值v。匿名函数的主体只是简单地将一个新的“反转”条目放入累加器(即 map),这样原始序列 v 的值就是键,而键 k 成为值。结果类似于应用 Clojure API 函数map-invert

请注意,有一个单独的 reduce-kv 函数用于减少关联集合(例如,地图)。 reduce-kv“为你解构”。这允许匿名函数写成:

(fn [m k v] (assoc m v k))

或者更简单的使用缩写:

#(assoc %1 %3 %2)

【讨论】:

    【解决方案2】:

    第一个 map 是空的,是一个可选的初始化值,它是传递给 reduce 函数的第一个参数。第二个映射是要减少其项目的集合。在这种情况下,每个项目都是一个MapEntry,并且它们作为第二个参数一次传递给归约函数。

    假设您的输入映射具有三个键/值对,reduce 函数将被调用 3 次。归约函数的m 参数指的是第一次调用时的初始化值(空映射),而分解 第二个参数k and v 来自迭代中传递的MapEntry 对。

    虽然大多数情况下归约函数在操作后返回第一个参数,但在您的示例中,它会反转第二个参数的键/值并将新对与初始化值相关联,但这并不是严格要求的所以..

    【讨论】:

      【解决方案3】:

      这意味着 reduce 映射 {:b 2 :a 1 :c 3} 和函数 (fn [m [k v]] (assoc m v k)) 依次从映射中获取键值对 [k v] 并将其与累加器哈希映射 m 相关联。累加器哈希映射的初始状态设置为空({})。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-03
        • 2015-12-01
        • 2013-12-22
        • 2019-05-19
        • 1970-01-01
        • 2011-08-03
        相关资源
        最近更新 更多