Как добавить поля на карту в Clojure? - PullRequest
9 голосов
/ 04 апреля 2011

У меня есть такая карта:

{:a 1 :b 20}

: и я хочу убедиться, что некоторые поля не пропущены на карте:

(:a :b :c :d )

: есть ли функцияобъединить два, что-то вроде:

(merge-missing-keys {:a 1 :b 20} (:a :b :c :d ))

: который может производить:

{:a 1 :b 20 :c nil :d nil}

?

Обновление:

С некоторыми указателями изответы, которые я нашел, что это можно сделать так:

(defn merge-missing-keys [
                           a-set 
                           some-keys
                         ]
          (merge-with 
                         #(or %1 %2) 
                         a-set  
                         (into {} (map (fn[x] {x nil}) some-keys))))

(merge-missing-keys {:a 1 :b 20} '(:a :b :c :d :e ))

Ответы [ 3 ]

6 голосов
/ 04 апреля 2011

Вы должны использовать merge-with:

Возвращает карту, которая состоит из остальных карт, соединенных на первый. Если ключ встречается в более чем одной карте, отображение (я) от последнего (слева направо) будет сочетаться с отображением в результат с помощью вызова (f val-in-result val-in-last).

Таким образом, следующее объединит все карты с одним фактическим значением, выбранным из карт, или nil.

(merge-with #(or %1 %2) 
            {:a 1 :b 2} 
            {:a nil :b nil :c nil :d nil})
; -> {:d nil :c nil :b 2 :a 1}

Вероятно, этого будет достаточно для построения вашей реализации.

4 голосов
/ 04 апреля 2011

Вы всегда можете просто объединить ваш массив по умолчанию следующим образом:

(merge
  {:a nil :b nil :c nil :d nil} ; defaults
  {:a 1 :b 20})                 ; current values

=> {:a 1, :b 20, :c nil, :d nil}
3 голосов
/ 04 апреля 2011

рифф на ответ @ mikera, чтобы он работал, когда у вас нет ключей, доступных как литералы:

(let [keys [:a :b :c :d]]
 (merge (zipmap keys (repeat nil))
        {:a 1 :b 20}))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...