【问题标题】:Sum of same objects with Array.reduce in JavascriptJavascript 中使用 Array.reduce 的相同对象的总和
【发布时间】:2022-01-09 18:20:06
【问题描述】:

我有一个这样的数组:

const inputArray = [
  {
    userId: 1,
    sum: 30,
  },
  {
    userId: 1,
    sum: 20,
  },
  {
    userId: 2,
    sum: 50,
  },
  {
    userId: 2,
    sum: 80,
  },
];

然后我写了一个函数,通过key对值求和,得到如下结果:

const output = [
  {
    userId: 1,
    sum: 50,
  },
  50,
  {
    userId: 2,
    sum: 130,
  },
  130,
];

如何纠正这个错误?功能代码如下:

const output = inputArray.reduce((accumulator, currentItem) => {
  const index = accumulator.findIndex((item) => item.userId === currentItem.userId);

  if (index < 0) {
    return [...accumulator, currentItem];
  } else {
    return [...accumulator, (accumulator[index].sum += currentItem.sum)];
  }
}, []);

【问题讨论】:

  • 预期结果是什么?
  • @VLAZ 我想他只是想要增加 sum 属性的同一个数组
  • @Nick 我认为在问题本身中包含所有相关信息会很好。
  • 这样写...

标签: javascript reduce


【解决方案1】:

试试

const inputArray = [
  {
    userId: 1,
    sum: 30,
  },
  {
    userId: 1,
    sum: 20,
  },
  {
    userId: 2,
    sum: 50,
  },
  {
    userId: 2,
    sum: 80,
  },
];

const output = inputArray.reduce((accumulator, currentItem) => {
  const matchedItem = accumulator.find((item) => item.userId === currentItem.userId);

  if (!matchedItem) {
    return [...accumulator, currentItem];
  } else {
    matchedItem.sum += currentItem.sum
    return accumulator
  }
}, []);

console.log(output)

即使该项目已经存在,您仍将新项目附加到累加器,您只需要对其进行变异。此外,由于您处理的是对象数组,因此您可以使用find,因为它将返回对匹配对象本身的引用,让您直接更新对象,而不必使用findIndex 然后使用索引来查找它再次在数组中

【讨论】:

  • 是的,它可以工作,但是这种方式会改变原始数组
  • 那么改变数组有什么问题?
【解决方案2】:

我建议,您可以简单地创建一个以 userId 为键和 sum 为值的对象,而不是 finding index,因为它可能会一次又一次地昂贵地迭代数组。

之后,你可以使用Object.entries(inputObj) 来制作对象数组。

var inputArray = [{ userId: 1,sum: 30},{userId: 1,sum: 20},{userId: 2,sum: 50},{userId: 2,sum: 80}];

var outputObj = inputArray.reduce((finalObj, curObj) => {
  if (!finalObj[curObj.userId]) finalObj[curObj.userId] = curObj.sum  //<--- adding new user if do not exist in the object
  else finalObj[curObj.userId] += curObj.sum; // <---- if already present, the add the sum
  return finalObj;
}, {})

var output = Object.entries(outputObj).map((obj) => ({
  userId: obj[0], //<--- key of object as userId
  sum: obj[1]  //<--- value of object as sum
}));

console.log(output)

【讨论】:

    【解决方案3】:

    你可以试试这个:

    const inputArray = [
      {
        userId: 1,
        sum: 30,
      },
      {
        userId: 1,
        sum: 20,
      },
      {
        userId: 2,
        sum: 50,
      },
      {
        userId: 2,
        sum: 80,
      },
    ];
    
    const res = Array.from(inputArray.reduce((m, {userId, sum}) => m.set(userId, (m.get(userId) || 0) + sum), new Map), ([userId, sum]) => ({userId, sum}));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 2021-05-21
      • 2016-09-30
      • 2012-07-13
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多