在Clojure中对地图矢量进行排序和排序的更清洁方法?

问题描述 投票:1回答:4

我有一个地图矢量,其中我需要删除名称键的值是重复的地图,保持具有最高年龄值的地图。我有一个解决方案,但我认为它看起来不干净。有没有更好的方法来做到这一点而不将其分解成多个功能?

这是我的数据:

(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})
clojure clojurescript
4个回答
5
投票

另一种方式是group-bymax-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})

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))

对于大型数据集,换能器应该更好


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

请注意我是如何通过q​​azxswpoi对每个:name组进行排序的,然后我将每个分组的最后一个进行排序。


0
投票

我会这样做有点不同,使用: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))
© www.soinside.com 2019 - 2024. All rights reserved.