Clojure:如何使用 set/union 进行比较
Clojure: how to use compare with set/union
为了举例,假设我有两组:
(def set-a #{{:id 1 :name "ABC" :zip 78759} {:id 2 :name "DEF" :zip 78759}})
(def set-b #{{:id 1 :name "ABC" :zip 78753} {:id 3 :name "XYZ" :zip 78704}})
我想找到集合之间的并集,仅使用 :id 和 :name 字段。但是,在不使用自定义比较器的情况下,我得到了集合中的四个元素,因为 :zip 字段不同。
(clojure.set/union set-a set-b)
#{{:id 3, :name "XYZ", :zip 78704} {:id 1, :name "ABC", :zip 78753}
{:id 1, :name "ABC", :zip 78759} {:id 2, :name "DEF", :zip 78759}}
使用自定义比较器或比较器查找两组之间并集的惯用方法是什么?
您可以使用 group-by
来做到这一点:
(map first (vals (group-by (juxt :id :name) (concat set-a set-b))))
或螺纹:
(->> (concat set-a set-b)
(group-by (juxt :id :name))
(vals)
(map first))
这是根据 key/values 即 (juxt :id :name)
的组合对元素进行分组。然后它获取生成的地图的 val
ues,然后 map
s first
获取每个分组中的第一个项目。
或者使用一些专门为此构建的代码,例如 distinct-by
。
请注意,这些方法适用于任何集合,而不仅仅是集合。
如果您不介意完全抛弃 :zip,请考虑使用 clojure。set/project。
(clojure.set/union
(clojure.set/project set-a [:id :name])
(clojure.set/project set-b [:id :name]))
#{{:id 3, :name "XYZ"} {:id 2, :name "DEF"} {:id 1, :name "ABC"}}
为了举例,假设我有两组:
(def set-a #{{:id 1 :name "ABC" :zip 78759} {:id 2 :name "DEF" :zip 78759}})
(def set-b #{{:id 1 :name "ABC" :zip 78753} {:id 3 :name "XYZ" :zip 78704}})
我想找到集合之间的并集,仅使用 :id 和 :name 字段。但是,在不使用自定义比较器的情况下,我得到了集合中的四个元素,因为 :zip 字段不同。
(clojure.set/union set-a set-b)
#{{:id 3, :name "XYZ", :zip 78704} {:id 1, :name "ABC", :zip 78753}
{:id 1, :name "ABC", :zip 78759} {:id 2, :name "DEF", :zip 78759}}
使用自定义比较器或比较器查找两组之间并集的惯用方法是什么?
您可以使用 group-by
来做到这一点:
(map first (vals (group-by (juxt :id :name) (concat set-a set-b))))
或螺纹:
(->> (concat set-a set-b)
(group-by (juxt :id :name))
(vals)
(map first))
这是根据 key/values 即 (juxt :id :name)
的组合对元素进行分组。然后它获取生成的地图的 val
ues,然后 map
s first
获取每个分组中的第一个项目。
或者使用一些专门为此构建的代码,例如 distinct-by
。
请注意,这些方法适用于任何集合,而不仅仅是集合。
如果您不介意完全抛弃 :zip,请考虑使用 clojure。set/project。
(clojure.set/union
(clojure.set/project set-a [:id :name])
(clojure.set/project set-b [:id :name]))
#{{:id 3, :name "XYZ"} {:id 2, :name "DEF"} {:id 1, :name "ABC"}}