首页 > 解决方案 > 使用 lodash 按键自定义总和元素

问题描述

我确实有两个包含键的对象

var a = {bar:[1,2], foo:[7,9]}
var b = {bar:[2,2], foo:[3,1]}

我想得到以下结果:

var c = {bar:[3,4], foo:[10,10]}

我已经有这样的for逻辑:

for (let key in b) {
  if (a[key]) {
      a[key][0] += b[key][0];
      a[key][1] += b[key][1];
  } 
  else a[key] = b[key];
}

但我想以一种时髦的方式来制作这个逻辑。我该怎么做?

标签: lodash

解决方案


您可以使用创建一个接收对象的函数,并使用其余参数n将它们收集到一个数组中。现在您可以将数组传播到组合对象中,并在定制器函数中使用lodash 的and对数组中的项目求和:_.mergeWith()Array.map()_.map()_.add()

const { mergeWith, isArray, map, add } = _

const fn = (...rest) => _.mergeWith({}, ...rest, (o = [], s) =>
  map(s, (n, i) => add(n, o[i]))
)

const a = {bar:[1,2], foo:[7,9]}
const b = {bar:[2,2], foo:[3,1]}
const c = {bar:[3,2], foo:[5,6]}
const d = {bar:[4,2], foo:[5,4]}

const result = fn(a, b, c, d)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

您还可以使用lodash/fp创建一个函数,使用 将所有值合并到一个多维数组_.mergeAllWith(),然后使用 转置数组_.zipAll(),并对每个数组求和:

const { rest, flow, mergeAllWith, isArray, head, mapValues, zipAll, map, sum } = _

const fn = rest(flow(
  mergeAllWith((o, s) => [...isArray(head(o)) ? o : [o], s]), // combine to a multidimensional array
  mapValues(flow(
    zipAll,
    map(sum)
  )),
))

const a = {bar:[1,2], foo:[7,9]}
const b = {bar:[2,2], foo:[3,1]}
const c = {bar:[3,2], foo:[5,6]}
const d = {bar:[4,2], foo:[5,4]}

const result = fn(a, b, c, d)

console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>


推荐阅读