在Clojure程序中,我有一个由包含人名和电子邮件的地图组成的数组.
例如
[
{ :name "John" :email "john@gmail.com" }
{ :name "Batman" :email "batman@gmail.com" }
{ :name "John Doe" :email "john@gmail.com" }
]
Run Code Online (Sandbox Code Playgroud)
我想删除重复的条目,为了进行比较,考虑具有相同电子邮件的对等于.在上面的示例中,输出将是:
[
{ :name "John" :email "john@gmail.com" }
{ :name "Batman" :email "batman@gmail.com" }
]
Run Code Online (Sandbox Code Playgroud)
在Clojure中实现这一目标的最佳方法是什么?有没有办法让不同的人知道什么等于使用功能?
谢谢.
lee*_*ski 13
还有另一种方法,有点更惯用,我想:
(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))))
Run Code Online (Sandbox Code Playgroud)
输出:
({:name "John", :email "john@gmail.com"}
{:name "Batman", :email "batman@gmail.com"})
Run Code Online (Sandbox Code Playgroud)
它是如何工作的:
(group-by :email items) 制作地图,其键是电子邮件,值是使用此电子邮件的记录组
{"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"}]}
Run Code Online (Sandbox Code Playgroud)
那么你只需要取其vals(记录组)并从中选择第一.
另一种方法是通过电子邮件创建一个排序集,因此它将所有具有相同电子邮件的记录视为相同的记录:
(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))
Run Code Online (Sandbox Code Playgroud)
输出:
#{{:name "Batman", :email "batman@gmail.com"}
{:name "John", :email "john@gmail.com"}}
Run Code Online (Sandbox Code Playgroud)
我真的不知道哪一个更具惯用性,而且性能更好.但我打赌第一个.
这样做可以:https://crossclj.info/fun/medley.core/distinct-by.html.
链接中的函数懒洋洋地遍历每个值并存储它看到的所有内容.如果coll已经看到了该值,则不会添加它.
然后你可以把它称为:(distinct-by #(% :email) maps),maps你的人物地图向量在哪里.
| 归档时间: |
|
| 查看次数: |
1455 次 |
| 最近记录: |