2014-09-01 4 views
0

특정 함수가 참이라고 평가되는 벡터의 모든 요소를 ​​찾으려고합니다. 내 시도가 실패했습니다. 아이디어?Clojure : 함수가 true로 평가되는 모든 벡터 찾기

(defn find-matches [match-fn elements] 
    (map-indexed 
    (fn [idx elem] 
     (if (= true (apply match-fn elem)) 
     [idx elem]) 
    elements)) 

(find-matches even? [1 2 3 4]) ; -> Arity Exception Wrong number of args (1) passed to: core$map-indexed clojure.lang.AFn.throwArity 
+1

'map'과'map-indexed'가 새로운 시퀀스를 하나씩 생성한다는 것을 기억하십시오. 하나는 순서 인수의 요소를가집니다. 'for'(일부는 응답으로 사용)에서'filter' 나'keep-indexed' 또는': when' 절을 사용하여 일부 요소를 유지하고 다른 요소를 버리는 것이 필요합니다. – Thumbnail

답변

3

fn 호출에 마지막 괄호가 누락되었습니다.

또한 컬렉션에만 적용되며 단일 항목에 대한 기능 만 사용하십시오.

user> 
(defn find-matches [match-fn elements] 
    (map-indexed 
    (fn [idx elem] 
     (if (= true (match-fn elem)) 
     [idx elem])) 
    elements)) 

#'user/find-matches 
user> (find-matches even? [1 2 3 4]) 
(nil [1 2] nil [3 4]) 

마지막으로, 배, 따라서 우리가 (= true x) 필요하지 않습니다 - 유지 색인 그래서 우리는 전무 요소를 무시할 수 있으며, 테스트에서 비 falsey 값 (사용의 일반적인 Clojure의 규칙을 사용하도록 전환 것 혼자 충분하다.)

(for [[idx elem] (map vector (range) my-vec) 
     :when (even? elem)] 
    idx) 
=> (1 4 6) 

또는 두 :

(filter (comp even? second) (map vector (range) my-vec)) 
=> ([1 2] [4 10] [6 22]) 
+0

+1은 OP를 미로에서 이끌어내는 데 어려움을 겪었습니다. – Thumbnail

+1

고맙습니다. 이것은 가장 정확하게 나의 질문에 답했고 Clojure 협약과 관용적 개발에 대해 매우 계몽 적이었습니다. – user1559027

4

는 소리. 원하지 않는 항목을 nil에 매핑하여 필터링하여 삭제할 수 있습니다.

(defn find-matches [pred coll] 
    (filter identity (map-indexed #(when (pred %2) %1) coll))) 

상관 값이지만 black spot로 할 것 인 음이 아닌 정수이지만 nil 같은 잘못된 것은 사소한 필터링한다. 예를 들어

,

(find-matches 
    #(.startsWith % "b") 
    (clojure.string/split "It's a braw bricht moonlicht nicht the nicht" #" ")) 
;(2 3) 

은 무한 순서에 대처할 수 있도록 그 결과, 게으른입니다 : 당신이 전체를 덤프하려면

(take 10 (find-matches even? (iterate inc 43))) 
;(1 3 5 7 9 11 13 15 17 19) 

당신은 vec에 포장 할 수 있습니다 벡터로 한정된 결과 :

1

결과는 일련의 숫자입니다 대신 당신이 인덱스를 원한다면

(def my-vec [1 2 5 9 10 15 22]) 
(filter even? my-vec) 
=> (2 10 22) 

filter처럼

user> 
(defn find-matches [match-fn elements] 
    (keep-indexed 
    (fn [idx elem] 
     (if (match-fn elem) 
      [idx elem])) 
    elements)) 

#'user/find-matches 
user> (find-matches even? [1 2 3 4]) 
([1 2] [3 4]) 
관련 문제