2010-12-31 24 views
6

Tôi có tham chiếu đến một vectơ [] có bản đồ được thêm vào đó. Nếu tôi muốn thay đổi giá trị của một mục bản đồ dựa trên kết hợp vị từ, cách thức thành ngữ để làm điều đó là gì?cách thành ngữ để cập nhật bản đồ khớp với vị từ trong một vector

Ví dụ ...

[ {: id 1: Cái tên "Joe"} { : id 2: tên "Fred"} ]

Và chúng tôi muốn cập nhật bất kỳ id của 2 với tên 'Brian'.

+0

xem: http://stackoverflow.com/questions/2330281/how-can-i-update-a -vector-item-in-clojure –

Trả lời

5

Dưới đây là một cách:

(def people [ { :id 1 :name "Joe" } { :id 2 :name "Fred" } ]) 

(defn brian-converter [person] 
    (if (= 2 (:id person)) 
     (assoc person :name "Brian") 
     person)) 

(map brian-converter people) 
;;=> ({:id 1, :name "Joe"} {:id 2, :name "Brian"}) 

Tùy thuộc vào cách mà bạn mong đợi những giá trị thay đổi, bạn có thể thích một cái gì đó linh hoạt hơn:

(defn create-converter [[key-to-match val-to-match] 
         key-to-replace val-to-replace] 
    (fn [person] 
    (if (= val-to-match (key-to-match person)) 
     (assoc person key-to-replace val-to-replace) 
     person))) 

(map (create-converter [:id 2] :name "Brian") people) 
;;=> ({:id 1, :name "Joe"} {:id 2, :name "Brian"}) 
(map (create-converter [:id 1] :name "Dude") people) 
;;=> ({:id 1, :name "Dude"} {:id 2, :name "Fred"}) 

Sự lựa chọn đại diện tham số (vector cho params tìm kiếm , đối số chưa được kiểm định cho các thay thế) trong create-converter là loại tùy ý đối với tôi; không chắc chắn nếu có một quy tắc cho điều đó.

3

Một cách khác là để tìm ra chỉ số của bản đồ bạn muốn cập nhật, sau đó cập nhật chỉ bản đồ mà [EDIT: đây là giả sử bạn chỉ muốn cập nhật một mục duy nhất trong vector]:

(def people [{:id 1 :name "Joe"} {:id 2 :name "Fred"}]) 

(defn vecmap-assoc-pred 
    [vm pred & kvs] 
    (let [i (some (fn [[i m]] (when (pred m) i)) 
       (map-indexed vector vm))] 
    (apply update-in vm [i] assoc kvs))) 

(vecmap-assoc-pred people #(= 2 (:id %)) :name "Brian") 

Đối với trường hợp cụ thể này, có thể có ý nghĩa hơn khi sử dụng bản đồ của mọi người, được khóa bằng id:

(def people {1 {:id 1 :name "Joe"} 2 {:id 2 :name "Fred"}}) 
(assoc-in people [2 :name] "Brian") 
Các vấn đề liên quan