如何基于嵌套值合并对?

haw*_*eye 1 merge clojure

鉴于 Clojure 中的以下列表:

(def pairs '[(2,1),(3,2),(2,4)])
Run Code Online (Sandbox Code Playgroud)

我想合并成对中这些基于重叠的第一项,并选择第二个值较大的项。

即我希望它们合并为:

[(3,2),(2,4)]   
Run Code Online (Sandbox Code Playgroud)

因为(2,1)(2,4)具有匹配的第一个值,并且(2,4)具有更大的第二个值,所以它会撞掉(2,1)

我的问题是:如何根据嵌套值合并对?

这是我尝试的:

(reduce
  (fn [first-pair second-pair]
    (if (not (= (first first-pair) (first second-pair)))
      (conj first-pair second-pair)
      (if (> (second first-pair) (second second-pair))
        first-pair
        second-pair)))
  pairs
  )
Run Code Online (Sandbox Code Playgroud)

lee*_*ski 5

最简单的方法是先将 all by 分组,然后在每个组中找到最大值:

user> (->> pairs
           (group-by first)
           vals
           (map (fn [data] (apply max-key second data))))
;;=> ((2 4) (3 2))
Run Code Online (Sandbox Code Playgroud)

您也可以一次性完成,无需中间序列:

user> (seq (reduce (fn [acc [f s]]
                     (update acc f (fnil max Double/NEGATIVE_INFINITY) s))
                   {} pairs))
;;=> ([2 4] [3 2])
Run Code Online (Sandbox Code Playgroud)