3

我是 Clojure 的初学者,我有一个简单的问题

可以说我有一个由地图组成的列表。每个地图都有一个 :name 和 :age

我的代码是:

(def Person {:nom rob :age 31 } )
(def Persontwo {:nom sam :age 80 } )
(def Persontthree {:nom jim :age 21 } )
(def mylist (list Person Persontwo Personthree))

现在我如何遍历列表。例如,假设我有一个给定的:name。我如何遍历列表以查看是否有任何地图:名称与我的:名称匹配。然后如果有匹配的地图,我如何获得该地图的索引位置?

-谢谢

4

6 回答 6

2
(defn find-person-by-name [name people] 
   (let
      [person (first (filter (fn [person] (= (get person :nom) name)) people))]
      (print (get person :nom))
      (print (get person :age))))

编辑:以上是问题的答案,因为它是在问题被编辑之前;这是更新的 -filter开始map变得混乱,所以我从头开始重写它loop

; returns 0-based index of item with matching name, or nil if no such item found
(defn person-index-by-name [name people] 
    (loop [i 0 [p & rest] people]
        (cond
            (nil? p)
                nil
            (= (get p :nom) name) 
                i
            :else
                (recur (inc i) rest))))
于 2009-07-14T05:36:34.873 回答
2

这可以通过doseq来完成:

(defn print-person [name people]
  (doseq [person people]
    (when (= (:nom person) name)
      (println name (:age person)))))
于 2009-07-14T05:45:34.903 回答
2

我建议查看过滤器功能。这将返回与某个谓词匹配的项目序列。只要您没有名称重复(并且您的算法似乎决定了这一点),它就可以工作。

于 2009-07-14T05:54:55.820 回答
1

既然你改变了你的问题,我给你一个新的答案。(我不想编辑我的旧答案,因为这会使评论变得非常混乱)。

可能有更好的方法来做到这一点......

(defn first-index-of [key val xs]
  (loop [index 0
         xs xs]
    (when (seq xs)
      (if (= (key (first xs)) val)
        index
        (recur (+ index 1)
               (next xs))))))

这个函数是这样使用的:

> (first-index-of :nom 'sam mylist)
1
> (first-index-of :age 12 mylist)
nil
> (first-index-of :age 21 mylist)
2
于 2009-07-14T06:21:40.103 回答
0

positionsclojure.contrib.seq(Clojure 1.2)使用怎么样?

(use '[clojure.contrib.seq :only (positions)])
(positions #(= 'jim (:nom %)) mylist)

它返回匹配索引的序列(您可以使用first或者take如果您想缩短列表)。

于 2011-11-28T15:07:26.993 回答
0
(defn index-of-name [name people]
  (first (keep-indexed (fn [i p]
                         (when (= (:name p) name)
                           i))
                       people)))

(index-of-name "mark" [{:name "rob"} {:name "mark"} {:name "ted"}])
1
于 2011-11-28T19:55:02.883 回答