我有一个地图矢量,其中我需要删除名称键值重复的地图,保留具有最高年龄值的地图。我有一个解决方案,但我认为它看起来不干净。有没有更好的方法来做到这一点而不将其分解成多个功能?
这是我的数据:
(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})
答案 0 :(得分:5)
另一种方式是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})
答案 1 :(得分:2)
简短版
(->> 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))
对于大型数据集,换能器应该更好
答案 2 :(得分:1)
不幸的是,您的原始解决方案实际上已被破坏。它似乎有效,因为你在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
请注意我是如何按:name
排序每个:age
组,然后我选择每个分组的最后一个。
答案 3 :(得分:0)
我会稍微改变一点,使用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))
结果:
grouped-data =>
{"jess" [{:name "jess", :age 32} {:name "jess", :age 35}],
"ruxpin" [{:name "ruxpin", :age 4}],
"aero" [{:name "aero", :age 33}],
"banner" [{:name "banner", :age 4}]}
name-age-maps =>
({"jess" 35} {"ruxpin" 4} {"aero" 33} {"banner" 4})
final-result =>
{"jess" 35, "ruxpin" 4, "aero" 33, "banner" 4}
答案 4 :(得分:0)
按不同权重和数据类型的向量字段进行比较(大小权重更大),大小为降序,名称为升序:
(def some-vector [{:name "head" :size 3}
{:name "mouth" :size 1}
{:name "nose" :size 1}
{:name "neck" :size 2}
{:name "chest" :size 10}
{:name "back" :size 10}
{:name "abdomen" :size 6}
])
(->> (some-vector)
(sort #(compare (str (format "%3d" (:size %2)) (:name %1))
(str (format "%3d" (:size %1)) (:name %2))
)))