2013-10-22 1 views
1

Clojure 글루 코드를 사용하여 동기화하려고 시도하는 두 개의 데이터베이스가 있습니다.투영 된 함수를 사용하여 차이 설정

clojure.set/difference과 같이 함수에서 투영 된 값에서 작동하는 것을 만들고 싶습니다.

(diff #{{:name "bob smith" :favourite-colour "blue"} 
     {:name "geraldine smith" :age 29}} 

     #{{:first-name "bob" :last-name "smith" :favourite-colour "blue"}} 

     :name 
     (fn [x] (str (:first-name x) " " (:last-name x)))) 

;; => {:name "geraldine smith" :age 29} 

내가 가진 것 중에 최고는 다음과 같습니다 : 여기

몇 가지 샘플 데이터의

(defn diff 
    "Return members of l who do not exist in r, based on applying function 
    fl to left and fr to right" 
    [l r fl fr] 
    (let [l-project (into #{} (map fl l)) 
     r-project (into #{} (map fr r)) 
     d (set/difference l-project r-project) 
     i (group-by fl l)] 
    (map (comp first i) d))) 

그러나 나는이 조금 unwieldly이라고 생각하고, 나는 그것이 매우 수행 상상할 수 없다 잘. 나는 계속 지키고 싶은 정보를 버리고 다시 찾는다.

내가했던

... 차이 집합 동안 주변의 원래 값을 유지하기 위해 메타 데이터를 사용하여 이동,하지만 작동하지 않았다, 그래서 나는, 기본 유형에 넣어 메타 데이터를 수없는 것 I이 왜 그런지 모르겠지만, 내 머리 속의 작은 목소리로 옆에있는 이런 종류의 조작이 모나드이고, 모나드가 무엇인지, 사용법을 알아 내야한다고 말하고 있습니다. . 작은 목소리가 옳은지에 대한 안내는 대단히 환영합니다!

답변

1
(defn diff 
    [l r fl fr] 
    (let [r-project (into #{} (map fr r))] 
    (set (remove #(contains? r-project (fl %)) l)))) 

이 더 이상 직접 차 작업을 노출하지 않습니다 (그것은 지금 remove/contains 조합 암시입니다)하지만, 간결하고 당신이 찾고있는 결과를 제공해야합니다.

예를 들어, 사용 및 출력 :

user> (diff #{{:name "bob smith" :favourite-colour "blue"} 
       {:name "geraldine smith" :age 29}} 

      #{{:first-name "bob" :last-name "smith" :favourite-colour "blue"}} 

      :name 
      (fn [x] (str (:first-name x) " " (:last-name x)))) 

#{{:age 29, :name "geraldine smith"}} 
+0

내가 여기 모나드 방법을 사용하지 않았고, 그것이 어떻게 작동하는지보고 관심이있을 것이지만, 어떤 수준에서 내가 볼 수없는 이유는 간단한 필터링 작업 set semantics를 사용하도록 강요되어야합니다. – noisesmith

+0

당신은 완전합니다. 나는 세트를 좋아한다! 나는 SQL을 쓰는 데 너무 많은 시간을 보냈다. :) –

관련 문제