在Clojure中对地图矢量进行排序和排序的更清洁方法?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Clojure中对地图矢量进行排序和排序的更清洁方法?相关的知识,希望对你有一定的参考价值。
我有一个地图矢量,其中我需要删除名称键的值是重复的地图,保持具有最高年龄值的地图。我有一个解决方案,但我认为它看起来不干净。有没有更好的方法来做到这一点而不将其分解成多个功能?
这是我的数据:
(def my-maps
[{:name "jess", :age 32}
{:name "ruxpin", :age 4}
{:name "jess", :age 35}
{:name "aero", :age 33}
{:name "banner", :age 4}])
这是我的解决方案:
(map first (vals (group-by :name (reverse (sort-by :name my-maps)))))
结果:
({:name "ruxpin", :age 4} {:name "jess", :age 35} {:name "banner", :age 4} {:name "aero", :age 33})
答案
另一种方式是group-by
和max-key
的组合。这种方法的优点是你不需要对你的集合进行排序,而sort
反过来又对性能产生影响,如果可以避免,它应该是。
(for [[_ vs] (group-by :name my-maps)]
(apply max-key :age vs))
;;=> ({:name "jess", :age 35}
;; {:name "ruxpin", :age 4}
;; {:name "aero", :age 33}
;; {:name "banner", :age 4})
另一答案
精简版
(->> my-set
(sort-by (juxt :name :age) #(compare %2 %1)) ; sort-by :name, :age in reverse order
(partition-by :name)
(map first))
换能器版本
(def xf (comp (partition-by :name) (map first)))
(->> my-set
(sort-by (juxt :name :age) #(compare %2 %1))
(into [] xf))
对于大型数据集,换能器应该更好
另一答案
不幸的是,您的原始解决方它似乎工作,因为你有my-set
中的数据的顺序。注意你从未实际按年龄排序,所以你永远不能保证年龄的顺序。
我通过另一次调用map
解决了这个问题:
(->> my-set (group-by :name)
(vals)
; Sort by age each list that group-by returns
(map #(sort-by :age %))
(map last)) ; This could also happen in the above map
请注意我是如何通过qazxswpoi对每个:name
组进行排序的,然后我将每个分组的最后一个进行排序。
另一答案
我会这样做有点不同,使用:age
函数而不是排序:
max
结果:
(def my-maps
[{:name "jess", :age 32}
{:name "ruxpin", :age 4}
{:name "jess", :age 35}
{:name "aero", :age 33}
{:name "banner", :age 4}])
(dotest
(let [grouped-data (group-by :name my-maps)
name-age-maps (for [[name map-list] grouped-data]
(let [max-age (apply max
(map :age map-list))
name-age-map {name max-age}]
name-age-map))
final-result (reduce into {} name-age-maps)]
final-result))
以上是关于在Clojure中对地图矢量进行排序和排序的更清洁方法?的主要内容,如果未能解决你的问题,请参考以下文章