Clojure返回seq中所有以第一个元素为键的对的列表

时间:2014-03-08 05:39:20

标签: clojure seq

我需要定义一个名为的函数 (get-all-pairs key seq)

它返回seq中所有以第一个元素为键的对的列表。如果没有对匹配,则返回空列表。

例如,如果我说宠物

(def pets
   '((cat 1) (dog 1) (fish 1) (cat 2) (fish 2))
)

(get-all-pairs 'cat pets)返回((cat 1) (cat 2))(get-all-pairs 'bird pets)返回'()

这是我的尝试:

(defn get-all-pairs [key seq]
  (cond
    (= key (first(first(seq)))) (cons (first seq) 
                                      (get-all-pairs key (rest seq)))
    :else '()))

但它不起作用。如果我打电话给它,它的消息如下:

#'proj2.proj2/pets
=> (get-all-pairs 'cat pets)
ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn  proj2.proj2/get-all-pairs (proj2.clj:20)

我不知道问题出在哪里。如何解决?

2 个答案:

答案 0 :(得分:6)

即时错误是因为您的定义中包含太多parens:(first (first (seq)))应该只是(first (first seq))。一旦你解决了这个问题,你的函数应该会运行完成,但是给出错误的答案:考虑()else是否真正符合你的需要。

一旦你完成了手动递归方法,试着弄清楚这个解决方案中发生了什么:

(defn get-all-pairs [k pairs]
  (filter #(= k (first %)) pairs))

答案 1 :(得分:1)

你走在正确的轨道上,但有点过分思考这一点。 For允许您抽象出您尝试手动执行的许多操作。在这种情况下,我们可以生成一个seq并迭代地使用if表达式:when。

(defn get-all-pairs [animal L]
  (for [k L
        :when (= animal (first k))]
    k))