Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure distinct中的习俗平等_Clojure - Fatal编程技术网

Clojure distinct中的习俗平等

Clojure distinct中的习俗平等,clojure,Clojure,在Clojure程序中,我有一个由包含人名和电子邮件的地图组成的数组 e、 g 出于比较的目的,我想删除重复条目,因为具有相同电子邮件的对是相等的。在上述示例中,输出为: [ { :name "John" :email "john@gmail.com" } { :name "Batman" :email "batman@gmail.com" } ] 在Clojure实现这一目标的最佳方式是什么?有没有办法让distinct知道使用什么等于函数 谢谢。这样就可以了:

在Clojure程序中,我有一个由包含人名和电子邮件的地图组成的数组

e、 g

出于比较的目的,我想删除重复条目,因为具有相同电子邮件的对是相等的。在上述示例中,输出为:

[
    { :name "John" :email "john@gmail.com" }  
    { :name "Batman" :email "batman@gmail.com" }  
 ] 
在Clojure实现这一目标的最佳方式是什么?有没有办法让distinct知道使用什么等于函数

谢谢。

这样就可以了:

链接中的函数惰性地遍历每个值,并存储所看到的所有内容。如果已经看到coll中的值,则不会添加该值


然后,您可以将其称为:distinct by%:email maps,其中maps是您的人物地图矢量。

还有另一种方法,我想更为惯用:

(let [items [{ :name "John" :email "john@gmail.com" }  
             { :name "Batman" :email "batman@gmail.com" }  
             { :name "John Doe" :email "john@gmail.com" }]]
  (map first (vals (group-by :email items))))
输出:

({:name "John", :email "john@gmail.com"} 
 {:name "Batman", :email "batman@gmail.com"})
#{{:name "Batman", :email "batman@gmail.com"} 
  {:name "John", :email "john@gmail.com"}}
这就是它的工作原理:

分组依据:电子邮件项生成一个地图,其键是电子邮件,值是此电子邮件的记录组

{"john@gmail.com" [{:name "John", :email "john@gmail.com"} 
                   {:name "John Doe", :email "john@gmail.com"}], 
 "batman@gmail.com" [{:name "Batman", :email "batman@gmail.com"}]}
然后,您只需获取其VAL记录组并从中选择第一个

另一种方法是通过电子邮件创建一个排序集,因此它会将具有相同电子邮件的所有记录视为相同的记录:

(let [items [{ :name "John" :email "john@gmail.com" }  
             { :name "Batman" :email "batman@gmail.com" }  
             { :name "John Doe" :email "john@gmail.com" }]]
  (into (sorted-set-by #(compare (:email %1) (:email %2))) items))
输出:

({:name "John", :email "john@gmail.com"} 
 {:name "Batman", :email "batman@gmail.com"})
#{{:name "Batman", :email "batman@gmail.com"} 
  {:name "John", :email "john@gmail.com"}}
真的不知道哪一个更地道,性能更好。但是我敢打赌第一个。distinct by可以很容易地实现为

(defn distinct-by [f coll]
  (let [groups (group-by f coll)]
    (map #(first (groups %)) (distinct (map f coll)))))
对于示例情况,可以使用如下方式

(distinct-by :email
             [{:name "John" :email "john@gmail.com"}  
              {:name "Batman" :email "batman@gmail.com"}  
              {:name "John Doe" :email "john@gmail.com"}])

由于关键字是函数,因此更惯用的调用方式是:电子邮件映射