我有以下数据结构(我相信两张地图)
{ :put [{:listId "myList", :entryId "1", :dateTime 1434637074},
{:listId "myList", :entryId "2", :dateTime 1434637075}],
:delete [{:listId "myList", :entryId "1"}]}
并希望删除:put
中已存在密钥listId
和entryId
的所有:delete
条目。结果应该是:
{ :put [{:listId "myList", :entryId "2", :dateTime 1434637075}],
:delete [{:listId "myList", :entryId "1"}]}
我尝试了以下但是1)它不是惯用的Clojure和2)它不会删除重复的条目。
(defn remove-add-if-duplicate [requests]
(doseq [delete (seq (:delete requests))]
(doseq [put (seq (:put requests))
:when (and (= (:listId delete) (:listId put))
(= (:entryId delete) (:entryId put))]
(disj (set (:put requests)) put)))
requests))
(remove-add-if-duplicate
{ :put [{:listId "myList", :entryId "1", :dateTime 1434637074},
{:listId "myList", :entryId "2", :dateTime 1434637075}],
:delete [{:listId "myList", :entryId "1"}]})
你能帮助我修改我的代码或向我展示一个很好的方法吗?
答案 0 :(得分:2)
(defn strip [data]
(let [ks (-> data :delete set)]
(update-in data [:put] #(remove (fn [m] (ks (select-keys m [:listId :entryId]))) %))))
例如,......
(def my-stuff { :put [{:listId "myList", :entryId "1", :dateTime 1434637074},
{:listId "myList", :entryId "2", :dateTime 1434637075}],
:delete [{:listId "myList", :entryId "1"}]})
(def processed { :put [{:listId "myList", :entryId "2", :dateTime 1434637075}],
:delete [{:listId "myList", :entryId "1"}]})
(= (strip my-stuff) processed);
;true
这与McSokoli's answer基本相同,但
some
来测试状态,update-in
应用于整个数据结构。您误解了Clojure数据结构的工作方式。处理它们的功能不会改变它们;相反,他们返回修改后的版本。
您使用doseq
是一种赠品。这返回nil
,因此只有副作用,在这种情况下没有副作用;也不应该。
您可以for
使用:where
来获得remove
的效果,但是没有意义。
答案 1 :(得分:1)
这应该可以胜任。
我们使用select-keys
仅保留来自输入:listId
中的条目的密钥(及其值):entryId
和:put
,以及remove
这样的条目在(:delete input)
中找到。
(def input {:put [{:listId "myList", :entryId "1", :dateTime 1434637074},
{:listId "myList", :entryId "2", :dateTime 1434637075}],
:delete [{:listId "myList", :entryId "1"}]}
(defn filtered [input]
{:delete (:delete input)
:put (remove #(some #{(select-keys % [:listId :entryId])}
(:delete input))
(:put input))})
测试它我们得到这个:
user> (filtered input)
{:delete [{:listId "myList", :entryId "1"}],
:put ({:listId "myList", :entryId "2", :dateTime 1434637075})}
或更多数据
user> (filtered {:put [{:listId "myList", :entryId "1", :dateTime 1434637074},
{:listId "myList", :entryId "2", :dateTime 1434637075}
{:listId "other", :entryId "3", :dateTime 1434637076}
{:listId "bestList", :entryId "4", :dateTime 1434637076}],
:delete [{:listId "myList", :entryId "1"}
{:listId "bestList" :entryId "4"}]})
{:delete [{:listId "myList", :entryId "1"} {:listId "bestList", :entryId "4"}],
:put ({:listId "myList", :entryId "2", :dateTime 1434637075}
{:listId "other", :entryId "3", :dateTime 1434637076})}