如何基于嵌套值合并对?

时间:2019-10-25 09:55:31

标签: merge clojure

给出Clojure中的以下列表:

(def pairs '[(2,1),(3,2),(2,4)])

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

即我希望它们合并为:

[(3,2),(2,4)]   

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

2 个答案:

答案 0 :(得分:4)

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

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

您也可以一次完成操作,而无需中间顺序:

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

答案 1 :(得分:2)

如果您不介意中间集合,则可以按first分组,并按每个分组的最大值进行分组。例如

user=> (map (partial apply max-key second) (vals (group-by first pairs)))
((2 4) (3 2))