【问题标题】:Remove Map from Vector when same keys exist in another Vector当另一个 Vector 中存在相同的键时,从 Vector 中删除 Map
【发布时间】:2016-09-26 12:33:15
【问题描述】:

我有以下数据结构(我相信有两个地图向量)

{ :put [{:listId "myList", :entryId "1", :dateTime 1434637074},
        {:listId "myList", :entryId "2", :dateTime 1434637075}],
  :delete [{:listId "myList", :entryId "1"}]}

并希望删除 :delete 中已存在键 listIdentryId 的任何 :put 条目。因此结果应该是:

{ :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"}]})

你能帮我修复我的代码或告诉我一个很好的方法吗?

【问题讨论】:

    标签: clojure


    【解决方案1】:
    (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的效果,但是没有意义。

    【讨论】:

      【解决方案2】:

      这应该可以完成工作。 我们使用select-keys 仅保留输入中:put 中条目中的键(及其值):listId:entryId,以及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})}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-13
        • 2014-05-24
        相关资源
        最近更新 更多