3

私は Clojure の初心者で、簡単な質問があります

マップで構成されたリストがあるとしましょう。各 Map には :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 があるとしましょう。リストをトラバースして、自分の :name と一致するマップの :name があるかどうかを確認するにはどうすればよいですか? そして、一致するマップがある場合、そのマップのインデックス位置を取得するにはどうすればよいですか?

-ありがとうございました

4

6 に答える 6

2

フィルタ機能を確認することをお勧めします。これにより、いくつかの述語に一致する一連のアイテムが返されます。名前の重複がない限り(そしてあなたのアルゴリズムがこれを指示しているように見える)、それは機能します。

于 2009-07-14T05:54:55.820 に答える
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 に答える
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

(Clojure 1.2)positionsからの使用はどうですか?clojure.contrib.seq

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

一致したインデックスのシーケンスを返します (リストを短くしたい場合はfirstorを使用できます)。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 に答える