Я хотел бы получить самый маленький элемент от вектора. Для этого я использую объединение 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
Уменьшение со стандартом min
возвраты 0 как ожидалось. Однако, когда я обеспечиваю свою собственную реализацию, она возвращается 2. Что я делаю неправильно?
Вам не хватает if
:
(reduce (fn [x y] (if (< x y) x y)) ...)
^-- note the if
работает отлично :-)
.fn, используемый с reduce, вероятно, должен обрабатывать 3 числа - 0, 1 и 2 аргумента.
Вам не хватает 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
Другими словами, функция, которую вы передаете, всегда возвращает 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)))