2014-09-01 88 views
0

我試圖找到某個特定函數計算結果爲true的向量中的所有元素。我的失敗嘗試是在下面。想法?Clojure:查找所有功能評估爲真的向量

(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'產生一個新的序列one-for-一個與他們的序列參數的元素。你需要''for''中的'filter'或'keep-indexed'或者':when'子句(就像這些答案一樣)來保留一些元素並丟棄其他元素。 – Thumbnail 2014-09-01 08:40:30

回答

3

您錯過了fn調用的最後一個paren。

此外,只適用於集合,只使用單個項目的功能。

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]) 

最後,我想切換到保索引,以便我們可以忽略爲零的元素,並使用使用測試(任何非falsey值一般Clojure的約定所以我們不需要(= true x),X單獨就足夠了)。

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]) 
+0

+ +1爲了讓OP走出迷宮而煩惱。 – Thumbnail 2014-09-01 08:50:45

+1

謝謝。這恰恰回答了我的問題,對Clojure慣例和習慣性發展非常有啓發。 – user1559027 2014-09-01 18:49:27

4

聽起來filter

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

相反,如果你想索引:

(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]) 
1

結果是數字的序列。我們可以通過將它們映射到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如果你想放棄整個的向量中的有限結果:

(vec (find-matches even? [1 2 3 4])) 
;[1 3]