2010-05-11 10 views
6

벡터에서 가장 작은 요소를 얻고 싶습니다. 이를 위해 reducemin 기능을 결합하여 사용합니다. min 내 자신의 구현을 제공하는 경우 그러나, 나는 예기치 않은 결과가 예상대로reduce 함수에서 예기치 않은 결과가 발생했습니다.

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를 반환합니다. 내가 뭘 잘못하고 있니?

(reduce (fn [x y] (if (< x y) x y)) ...) 
        ^-- note the if 

잘 작동 :

답변

8

당신은 if이없는 것입니다. :-)

-1

fn은 reduce와 함께 사용되어 아마 0, 1 및 2 인수 3 개를 처리해야합니다.

+1

정말. 'min'의 구현은 Clojure 자체에서 무효 구현을 가지지 않는 함수에서 사용되는'reduce'의 예제를 제공합니다. 또한, 단항 사례는 Clojure의'reduce'에 의해 사용되지 않습니다. 길이 1의시 v 스는 항 s 유일한 요소로 축소됩니다. 궁극적으로 빈 시퀀스를 처리하려는 경우 null 입력이 필요합니다 (입력을 잘못된 입력으로 처리하려는 경우이를 사용하지 않고 수행 할 수 있고 이진 케이스가 필요합니다.) 길이가 1보다 큰 시퀀스를 다루는 경우, 어쨌든'reduce '를 사용하는 것은 의미가 없습니다.) –

+0

@Michal, 아 맞습니다. 0과 2 개의 인수. – dnolen

5

함수 몸체에 if이 누락되었습니다. 이제 어떻게 일이있다 : 마지막 반복이 반환됩니다 그렇게 2 당신이 감소 시퀀스의 마지막 숫자이기 때문에

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를 반환합니다.

또한 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))) 
관련 문제