1

Clojure グルー コードを少し使用して、同期を維持しようとしている 2 つのデータベースがあります。

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)))

しかし、これは少し扱いに​​くいと感じており、あまりうまく機能するとは想像できません。残しておきたい情報を捨てて、また調べています。

セットの違いの間に元の値を維持するために、メタデータを使用してみましたが、プリミティブ型にメタデータを配置できないようで、うまくいきませんでした...

理由はわかりませんが、頭の中で小さな声が聞こえてきて、モナドの目的はこの種の操作であり、モナドとは何か、どのように使用するかを実際に調べる必要があることを教えてくれます。それ。小さな声が正しいかどうかについてのガイダンスは大歓迎です!

4

1 に答える 1

2
(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"}}
于 2013-10-22T17:36:21.323 に答える