保留一组实用函数可以使处理这类问题几乎是微不足道的。
我的解决方案是编写这个函数:
const combine = reduce (mergeWith (concat)) ({})
基于我的实用函数reduce、concat 和mergeWith。然后它很简单:
combine (a) //=> {26: [0, 0, 0], 27: [100, 100, 100], 28: [0, 0, 0]}
const reduce = (f) => (init) => (xs) => xs .reduce ((a, x) => f (a, x), init)
const concat = (a) => (b) => a .concat (b)
const mergeWith = (f) => (a, b) => Object .fromEntries (
[... new Set ([... Object .keys (a), ... Object .keys (b)])] .map (
(k) => [k, k in a ? (k in b ? f (a [k]) (b [k]) : a [k]) : b [k]]
)
)
const combine = reduce (mergeWith (concat)) ({})
const a = [{26: [0], 27: [100], 28: [0]}, {26: [0], 27: [100], 28: [0]}, {26: [0], 27: [100], 28: [0]}]
console .log (combine (a))
.as-console-wrapper {max-height: 100% !important; top: 0}
reduce和concat除了转换Array .prototype方法into pure功能.1在每种情况下,新函数都是完全柯里化的,例如,您将调用reduce (tranformer) (initialValue) (values) 而不是values .reduce (transformer, initialValue)。这种风格通常使编写函数更容易。
mergeWith参与度更高。它执行两个对象的浅合并,只要两个对象都具有给定的键,就对两个对象的相关属性使用提供的函数,否则使用唯一提供的属性。
一旦我们有了这些辅助函数,那么编写起来就变得非常简单了。我们用concat 配置mergeWith,并将这个结果函数和空对象传递给reduce。
const combine = reduce (mergeWith (concat)) ({})
1reduce 不会像Array.prototype.reduce 那样向转换函数提供所有参数。这有充分的理由,不值得在这里讨论,但如果你想要它们,我们可以将实现简化为 const reduce (f) => (init) => (xs) => xs .reduce (f, init)。