2

レコードをその要素で更新する方法

(pprint records)
({:Name "John" :Age 12 :Index 123 :Class_Index}
 {:Name "Joe" :Age 13 :Index 3 :Class_Index}
 {:Name "Jon" :Age 14 :Index 4 :Class_Index})

年齢 + インデックスに基づいて class_index が更新されるような関数を作成するにはどうすればよいですか。同時に、関数の実行後に出力が次のようになるようにレコードを更新できます

(pprint records)
({:Name "John" :Age 12 :Index 123 :Class_Index 135}
 {:Name "Joe" :Age 13 :Index 3 :Class_Index 16}
 {:Name "Jon" :Age 14 :Index 4 :Class_Index 18})

ただし、行が多すぎるため、レコードのすべての要素を手動で入力することはできません。あなたの答えの機能はまだ使用できますか? pprint は単に説明のためのものです。実際、私のレコードには代わりに多くの要素が含まれます。

意味で (def records (atom [records])) または行を反復処理する必要があり、メモリを大量に消費します。これを行うより効率的な方法はありますか。

4

2 に答える 2

2

常に一度にレコードを更新する場合

(def records (atom [(->Record "John" 12 123 nil)
                    (->Record "Joe" 13 3 nil)
                    (->Record "Jon" 14 4 nil)]))

(reset! records (map #(assoc % :Class_Index (+ (:Age %) (:Index %)))
                     @records))

(pprint records)
-> #<Atom@131bf42: 
     ({:Name "John", :Age 12, :Index 123, :Class_Index 135}
      {:Name "Joe", :Age 13, :Index 3, :Class_Index 16}
      {:Name "Jon", :Age 14, :Index 4, :Class_Index 18})>

さもないと

(def records [(ref (->Record "John" 12 123 nil))
              (ref (->Record "Joe" 13 3 nil))
              (ref (->Record "Jon" 14 4 nil))])

(dosync (doseq [record records]
          (alter record #(assoc % :Class_Index (+ (:Age %) (:Index %))))))

(pprint records)
-> [#<Ref@178f7a8: {:Name "John", :Age 12, :Index 123, :Class_Index 135}>
    #<Ref@129617b: {:Name "Joe", :Age 13, :Index 3, :Class_Index 16}>
    #<Ref@ac9126: {:Name "Jon", :Age 14, :Index 4, :Class_Index 18}>]

アップデート。コレクションに多くの要素がある場合は、レコード オブジェクトの代わりに clojure マップを使用することをお勧めします。レコード定義をマップに置き換えるだけ

(def records (atom [{:Name "John", :Age 12, :Index 123, :Class_Index nil}
                    {:Name "Joe", :Age 13, :Index 3, :Class_Index nil}
                    {:Name "Jon", :Age 14, :Index 4, :Class_Index nil}]))

またはアイテムのソースがある場合

(def records (atom (source-fn ...)))

この場合、メモリのオーバーヘッドはありません。残りのコードは同じです。

于 2013-01-03T15:30:12.920 に答える
0

Clojureのコンテキストでは、レコードはマップを構造化する方法であることに注意してください(データベースからのレコードを意味していると思います)。あなたの質問に関して:

    ; The database
(def people [
  {:Name "John" :Age 12 :Index 123}
  {:Name "Joe" :Age 13 :Index 3}
  {:Name "Jon" :Age 14 :Index 4}])

; Calculates the class index for a person and returns the updated person
(defn class-index [{:keys [Age Index] :as person}]
    (assoc person :Class_Index (+ Age Index)))

; Calculate the class index for all people
(pprint (map class-index people))

; Output
; ({:Name "John", :Age 12, :Class_Index 135, :Index 123}
; {:Name "Joe", :Age 13, :Class_Index 16, :Index 3}
; {:Name "Jon", :Age 14, :Class_Index 18, :Index 4})
于 2013-01-08T15:11:14.953 に答える