Как получить модифицированный Set после обновления элемента для определенного ключа? - PullRequest
1 голос
/ 11 марта 2012

У меня есть набор предметов

(def books #{{:isbn 1 :title "Programming Clojure"}
             {:isbn 2 :title "Joy of Clojure"}
             {:isbn 3 :title "Clojure in Action"}})

Как обновить объект, имеющий заданный ключ (: isbn), и вернуть измененный набор?

(??? books :isbn {:isbn 1 :title "Programming Clojure" :author "Halloway"})

В Java равенство может быть определено с помощью isbn, и элемент может быть непосредственно добавлен в Set. Каков идиоматический способ сделать это в Clojure?

Ответы [ 3 ]

2 голосов
/ 11 марта 2012

Если вы хотите делать такие обновления, у вас должна быть ассоциативная структура.Но вы можете превратить набор в единицу, а затем обратно:

(-> (group-by :isbn books)
    (assoc-in [1 0 :author] "Halloway") ; 1 is the isbn, 0 means "first"
    vals 
    (->> (map first)) 
    set)

В этом коде предполагается, что isbn уникален (так как вы сказали «ключ»).Он превращает набор в карту из: значений isbn в последовательности соответствующих записей, обновляет первую запись с помощью :isbn 1 с автором, а затем переносит ее обратно в набор.

0 голосов
/ 14 марта 2012

Следующие функции Clojure, update-if-isbn - непубличная функция, решат вашу проблему.

(defn- update-if-isbn [isbn k v book] 
  (if (= (:isbn book) isbn) (assoc book k v) book))

(defn update-books [isbn k v books] 
  (set (map (partial update-if-isbn isbn k v) books)))
0 голосов
/ 11 марта 2012

Исходя из предположения, что вы используете номер ISBN в качестве «ключа», вот мое решение

(defn update-set [coll k new-map]
   (reduce (fn [new-set existing-map] 
             (if (= (k existing-map) (k new-map)) 
               (conj new-set new-map) 
               (conj new-set existing-map))) #{} coll)) 

(update-set books :isbn {:isbn 1 :title "Programming Clojure" :author "Halloway"})
; => #{{:title "Joy of Clojure", :isbn 2} {:author "Halloway", :title "Programming Clojure",   :isbn 1} {:title  "Clojure in Action", :isbn 3}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...