合并一系列地图

时间:2014-06-30 12:02:57

标签: clojure hashmap

我有两张地图:

(def h1 {:p1 {:x {:port :p1 :instr :x :qty 10}}})
(def h2 {:p1 {:y {:port :p1 :instr :y :qty 11}}})

当我使用

合并它们时
(apply (partial merge-with merge) [h1 h2])

我得到了正确的结果:

-> {:p1 {:y {:port :p1, :qty 11, :instr :y}, :x {:port :p1, :qty 10, :instr :x}}

但是,如果我尝试减少一系列地图:

(reduce (fn [r m] apply (partial merge-with merge) r m) {} [h1 h2])

我只得到第一张地图:

-> {:p1 {:y {:port :p1, :qty 11, :instr :y}}}

我希望得到同样的结果。我做错了什么?

1 个答案:

答案 0 :(得分:4)

您忘记应用apply。在

(fn [r m] apply (partial merge-with merge) r m)

... do形式的隐式fn执行一系列评估,返回最后一个的结果。忽略副作用(并且没有),该功能相当于

(fn [r m] m)
正如你所观察到的那样。

reduce将地图序列分开,因此您不需要apply

(reduce (fn [r m] (merge-with merge r m)) {} [h1 h2])
; {:p1
;  {:y {:qty 11, :instr :y, :port :p1},
;   :x {:qty 10, :instr :x, :port :p1}}}

如果您决定对该功能使用相同的结构,则必须这样做:

(reduce (fn [r m] (apply (partial merge-with merge) [r m])) {} [h1 h2])
; {:p1
;  {:y {:qty 11, :instr :y, :port :p1},
;   :x {:qty 10, :instr :x, :port :p1}}}

apply期望一个序列作为它的最后一个参数,它将变为第一个(函数)参数的尾随参数。