2014-11-25 2 views
3

Clojure에서 여러 맵을 병합하려고합니다.Clojure가 병합되어 nil 값을 무시합니다.

(defn deep-merge 
    [& xs] 
(if (every? map? xs) 
    (apply merge-with deep-merge xs) 
    (last xs))) 

이 솔루션의 문제는지도 중 하나가 전무 경우, 그것은 이전의 모든 맵을 삭제하는 것입니다 (그래서 마지막지도가 전무 인 경우 : 나는 대부분의이 같은 모양, 온라인 많은 솔루션을 발견 , 전체 함수는 nil을 반환합니다). nil 값을 무시하는 정규 병합 함수에서는 그렇지 않습니다. nil 값을 무시하는 다른 간단한 병합 구현이 있습니까?

답변

5

나는 이것을 https://github.com/circleci/frontend/blob/04701bd314731b6e2a75c40085d13471b696c939/src-cljs/frontend/utils.cljs에서 찾았습니다. 그것은 정확히 그것이해야 할 일을합니다.

(defn deep-merge* [& maps] 
    (let [f (fn [old new] 
      (if (and (map? old) (map? new)) 
       (merge-with deep-merge* old new) 
       new))] 
    (if (every? map? maps) 
     (apply merge-with f maps) 
    (last maps)))) 

(defn deep-merge [& maps] 
    (let [maps (filter identity maps)] 
    (assert (every? map? maps)) 
    (apply merge-with deep-merge* maps))) 

서클시 사용자에게 감사합니다.

+1

후손을 위해 이것은 원래'clojure '에 있던 내용을 변형 한 것 같다. 기여자 '를 영입하지 못하고 유지 보수를받지 못해서'clojure.core'에 들어간 적이 없다. 이 문제와 원본 코드에 대한 링크는 http://dev.clojure.org/jira/browse/CLJ-1468에서 찾을 수 있습니다. – lsh

2

nil을 즉시 제거 하시겠습니까?

(defn deep-merge [& xs] 
    (let [xs (remove nil? xs)] 
    (if (every? map? xs) 
     (apply merge-with deep-merge xs) 
     (last xs)))) 
+0

불행하게도 여전히 병합과 동일한 동작을 제공하지 않습니다. 'nil'값의 경우 병합은 해당 값을 고려하지만 구현은 그렇지 않습니다. 예 : (병합 {: a 3} {: a nil}) => {: a nil}, 그러나 (깊은 병합 {: a 3} {: a nil}) => {: a 3} – Asher

+0

@Asher 나는 그 질문이 명확해질 필요가 있다고 생각한다. 그것은 정규 병합 함수가 * nil 값을 무시한다는 것을 나타냅니다 *. 이제 병합은 그 값을 고려합니다 *. 그리고이 질문은 merge *와 같은 동작이 아닌 nil 값을 무시하는 deep-merge 구현을 쉽게 요구합니다. 하나 또는 두 가지 예가 도움이 될 수 있습니다. 나는이 솔루션이 당신이 찾고있는 것이 아니라는 사실을 받아들입니다. – Thumbnail

+0

차이점을 설명해 드리겠습니다. 병합중인 ** 맵 ** 중 하나가 nil이면 병합이 무시합니다. 그러나 맵 내의 ** 값 ** 중 하나가 nil이면 병합은이를 무시하지 않습니다. 사례 1의 예 : (merge {: a 1} nil {: b 2}) => {: a 1 : b 2}. case 2의 예 : (merge {: a 1} {: a nil} {: b 2}) => {a nil : b 2} – Asher

관련 문제