You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure中两个reduce表达式执行结果不一致的原因咨询

Clojure中两个reduce表达式执行结果不一致的原因咨询

嘿,我来帮你拆解这两个reduce为啥结果差这么多~核心问题出在初始累加器的处理逻辑上,咱们一步步看:

首先,你给两个reduce的初始累加器都是{},也就是第一次调用匿名函数的时候,:minimum和:maximum的值都是nil,这是关键的起点。

先看第一个reduce的问题

(reduce (fn [{:keys [minimum maximum]} new-number]
          {:minimum (if (and minimum (< new-number minimum))
                      new-number
                      minimum)
           :maximum (if (and maximum (> new-number maximum))
                      new-number
                      maximum)})
        {}
        [5 23 5004 845 22])
  • 处理:minimum时,判断条件是(and minimum (< new-number minimum)):第一次执行时,minimum是nil,and表达式直接返回nil,条件不成立,所以返回的还是minimum也就是nil。后面每一次循环,minimum始终是nil,这个条件永远满足不了,最后:minimum就一直是nil。
  • 同理,:maximum的判断条件(and maximum (> new-number maximum)),因为maximum一开始是nil,同样永远触发不了更新,最后也保持nil。所以整个reduce返回的就是{:minimum nil, :maximum nil}。

再看第二个reduce的修正逻辑

(reduce (fn [{:keys [minimum maximum]} new-number]
          {:minimum (if (and minimum (> new-number minimum))
                      minimum
                      new-number)
           :maximum (if (and maximum (< new-number maximum))
                      maximum
                      new-number)})
        {}
        [5 23 5004 845 22])

它把判断逻辑和返回值完全反过来了,刚好解决了初始值为nil的问题:

  • 处理:minimum时,判断条件是(and minimum (> new-number minimum)):第一次minimum是nil,条件不成立,这时候直接返回new-number也就是第一个元素5,这样累加器里的:minimum就有了有效值。后面再处理其他元素时,只要新元素比当前最小值大,就保留原来的最小值;如果更小,就更新为新元素,完美实现了最小值跟踪。
  • 处理:maximum时,判断条件(and maximum (< new-number maximum)):第一次maximum是nil,条件不成立,返回第一个元素5;遇到23时,(and 5 (<23 5))不成立,返回23更新最大值;遇到5004时同理,返回更大的5004,这样就能正确得到最大值了。

总结来说,第一个reduce的逻辑在初始值为nil时完全无法启动更新,而第二个reduce通过反转判断逻辑,在初始阶段就把第一个元素赋值给了min和max,后续的比较才能正常运作~

备注:内容来源于stack exchange,提问作者Antonio Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 08:30:28