我需要实现一个带有两个映射向量的函数,并返回一种组合的一个映射向量。详情如下:
输入1:
[{:id 1 :car "A" :price 10}{:id 2 :car "B" :price 20}{:id 3 :car "C" :price 30}]
输入2:
[{:id 4 :car "A" :price 5}{:id 5 :car "B" :price 30}{:id 6 :car "D" :price 40}]
输出:
[{:id 4 :car "A" :price 5} {:id 2 :car "B" :price 20} {:id 3 :car "C" :price 30} {:id 6 :car "D" :price 40}]
也就是说,如果:car
相同,请选择最低价格,或直接将:id
添加到输出中。
我已经考虑使用map来获取嵌套循环中的每个值,但我相信这不是一个很好的方法。然后我学习了类似clojure.walk和juxt的内容,但它们看起来很花哨,需要更多解释。
我认为另一种可能的抽象解决方案是将它们连在一起,并使用标记检查矢量中的每个地图以检查价格。拿起最小的并移除较大的。
我希望你能帮助我,非常感谢你!
答案 0 :(得分:4)
执行此操作的一种方法是按:car
对项目进行分组,然后找到每个组的最低价格值:
user> (->> (concat data1 data2)
(group-by :car)
vals
(map #(apply min-key :price %)))
;;=>({:id 4, :car "A", :price 5} {:id 2, :car "B", :price 20} {:id 3, :car "C", :price 30} {:id 6, :car "D", :price 40})
您也可以使用reduce
进行一次传递,这有点冗长,但应该有更好的效果:
(defn process [& colls]
(vals (reduce (fn [acc {car :car :as item}]
(if (acc car)
(update acc car (partial min-key :price) item)
(assoc acc car item)))
{}
(apply concat colls))))
user> (process data1 data2)
;;=> ({:id 4, :car "A", :price 5} {:id 2, :car "B", :price 20} {:id 3, :car "C", :price 30} {:id 6, :car "D", :price 40})