我在Clojure中有两个地图向量
(def a [{:name "batman" :universe "DC" :email "[email protected]"}
{:name "flash" :universe "DC" :email "[email protected]"}
{:name "thor" :universe "MARVEL" :email "[email protected]"}])
(def b [{:name "batman" :universe "DC" :email "[email protected]"}
{:name "flash" :universe "DC" :email "[email protected]"}
{:name "thor" :universe "MARVEL" :email "[email protected]"}
{:name "riddler" :universe "DC" :email "[email protected]"}])
:name
两个列表中的属性始终保持同步;即,batman
ina
也总是batman
打开b
。
不过,我要做的是仅选择电子邮件不匹配的行。
(stuck-on-what-to-write-here)
=> ({:name "flash", :universe "DC", :email "[email protected]"})
如果我用
(filter #(not (contains? (set (map :email a)) (:email %))) b)
它返回2行,其中一行与之flash
不匹配,而另一行与riddler
因为..好吧,它不在a中,因此不匹配!
我需要怎么做才能获得闪光而不是骑手?
(defn mismatch?
"Returns true if there is any mismatch between corresponding items."
[a b]
(= (count (clojure.set/union (set a) (set b)))
(max (count a) (count b))))
如果您想要一个特定的名称,则可以使用列表理解:
(defn get-mismatched-emails
"Returns the name of any superheroes with inconsistent contact records."
[a b]
(for [i a j b
:when (and (= (:name i) (:name j))
(not= (:email i) (:email j)))]
(:name i)))
请注意,此函数效率很低,因为它必须比较两个列表之间的每个对组合。只需将数据结构更改为地图即可:
{"batman" {:universe "DC" :email "[email protected]"}
"flash" {:universe "DC" :email "[email protected]"}
"thor" {:universe "MARVEL" :email "[email protected]"}}
您宁可轻松地将所需内容扩展到更大的数据集。
(for [name (clojure.set/union (set (keys a))
(set (keys b)))
:when (detect-mismatched-data (a name) (b name))]
name)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句