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 记录(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 回答