代码之家  ›  专栏  ›  技术社区  ›  Jessie Richardson

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

  •  0
  • Jessie Richardson  · 技术社区  · 7 年前

    我有一个映射向量,其中我需要删除name键值重复的映射,保留年龄值最高的映射。我有一个解决方案,但我认为它看起来不干净。有没有更好的方法可以在不将其分解为多个功能的情况下实现它?

    以下是我的数据:

    (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})
    
    5 回复  |  直到 7 年前
        1
  •  5
  •   leetwinski    7 年前

    另一种方法是 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})
    
        2
  •  2
  •   ka yu Lai    7 年前

    简短版本

    (->> my-set
         (sort-by (juxt :name :age) #(compare %2 %1)) ; sort-by :name, :age in reverse order
         (partition-by :name)
         (map first))
    

    a传感器版本

    (def xf (comp (partition-by :name) (map first)))
    (->> my-set
         (sort-by (juxt :name :age) #(compare %2 %1))
         (into [] xf))
    

    对于大数据集,传感器应更好

        3
  •  1
  •   Carcigenicate    7 年前

    不幸的是,您原来的解决方案实际上被破坏了。这似乎是因为数据的顺序 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 , 然后 我取每组的最后一个。

        4
  •  0
  •   Alan Thompson    7 年前

    我会用不同的方法 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}
    
        5
  •  0
  •   surfealokesea    4 年前

    按不同权重和数据类型的向量字段进行比较(大小权重更大),大小为降序,名称为升序:

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