我想从矢量中获取最小的元素.为此,我使用组合reduce和min功能.但是,当我提供自己的实现时,min我会得到意想不到的结果:
user=> (reduce (fn [x y] (< x y) x y) [1 2 3 2 1 0 1 2])
2
user=> (reduce min [1 2 3 2 1 0 1 2 3])
0
Run Code Online (Sandbox Code Playgroud)
标准减少min按预期返回0.但是,当我提供自己的实现时,它会返回2.我做错了什么?
你错过了一个if:
(reduce (fn [x y] (if (< x y) x y)) ...)
^-- note the if
Run Code Online (Sandbox Code Playgroud)
工作良好.:-)
你错过if了这个功能的身体.现在发生的事情是:
user> (use 'clojure.contrib.trace)
nil
user> (defn foo [x y] (< x y) x y)
#'user/foo
user> (dotrace [foo] (reduce foo [1 2 3 2 1 0 1 2]))
TRACE t2229: (foo 1 2)
TRACE t2229: => 2
TRACE t2230: (foo 2 3)
TRACE t2230: => 3
TRACE t2231: (foo 3 2)
TRACE t2231: => 2
TRACE t2232: (foo 2 1)
TRACE t2232: => 1
TRACE t2233: (foo 1 0)
TRACE t2233: => 0
TRACE t2234: (foo 0 1)
TRACE t2234: => 1
TRACE t2235: (foo 1 2)
TRACE t2235: => 2
2
Run Code Online (Sandbox Code Playgroud)
换句话说,您传入的函数始终返回y,因此在最后一次迭代中返回2,因为2是您减少的序列的最后一个数字.
另请注意,min已基于reduce:
(defn min
"Returns the least of the nums."
([x] x)
([x y] (if (< x y) x y))
([x y & more]
(reduce min (min x y) more)))
Run Code Online (Sandbox Code Playgroud)