gpt4 book ai didi

clojure - 你如何在clojure中通过键找到 map 集的交集?

转载 作者:行者123 更新时间:2023-12-04 02:12:32 24 4
gpt4 key购买 nike

此函数接受一组数字向量并返回它们的交集:

(defn foo [& sets] (apply clojure.set/intersection (map #(set %) sets)))

例如。

user=> (foo [1 2 3] [3 4 5 1] [33 3 3 1])
#{1 3}

假设输入集的元素是带有 :id 键用作 map 的唯一属性的 map ,您如何实现同样的事情?

即。我正在尝试编写一个执行此操作的函数 foo2:

user=> (foo2 [{:id 1 ...} {:id 2 ...} {:id 3 ...}] 
[{:id 3 ...} {:id 4 ...} {:id 5 ...} {:id 1 ...}]
[{:id 33 ...} {:id 3 ...} {:id 3 ...} {:id 1 ...}])
[{:id 1 ...} {:id 3 ...}]

有没有简单的方法可以做到这一点?

或者是收集 ID、获取键的交集然后在输入集中查找键的唯一方法?

有什么方法可以通过定义一个返回任意对象键的“键值”函数来“重载”集合函数(并集、交集等),或者是否只能将集合与原语一起使用值(value)观?

最佳答案

编辑:我之前错误地假设具有相同 :id 的映射保证具有相同的键和值。如果允许它们不同,这是一个更好的答案:

(defn intersect-by [key-fn data]
(let [normalized (map (fn [map-data]
(->> map-data
(group-by key-fn)
(map (fn [[key val]]
[key (apply merge val)]))
(into {})))
data)
normalized-keys (map (comp set keys) normalized)
intersection (apply clojure.set/intersection normalized-keys)
merged-data (apply merge-with merge normalized)]
(vals (select-keys merged-data intersection))))
#'user/foo

(def data [[{:id 1} {:id 2} {:id 3, :x 3}]
[{:id 3, :y 4} {:id 4} {:id 5} {:id 1}]
[{:id 33} {:id 3} {:id 3, :z 5} {:id 1}]])
#'user/data

(intersect-by :id data)
({:id 1} {:id 3, :x 3, :y 4, :z 5})

如果您假设具有相同 :id 的两个映射保证具有相同的键和值,那么您的第一个 foo 函数已经这样做了:

(def data [[{:id 1} {:id 2} {:id 3}]
[{:id 3} {:id 4} {:id 5} {:id 1}]
[{:id 33} {:id 3} {:id 3} {:id 1}]])
#'user/data

(defn foo [& sets] (apply clojure.set/intersection (map #(set %) sets)))
#'user/foo

(apply foo data)
#{{:id 1} {:id 3}}

关于clojure - 你如何在clojure中通过键找到 map 集的交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36867070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com