合并数组并添加类似对象的数量

时间:2018-04-23 21:58:06

标签: javascript

我有一个包含日期和数量的对象数组(以及其他内容)。

每个日期都有一个具有特定金额的对象,但同一日期也可能有多个对象包含不同的金额。

我想整合这些对象,所以我在每个日期的数组中只有一个对象......并且对应于该日期的金额是这些对象中所有先前金额的总和。

示例可能对此有所帮助:

我的数组现在的样子:

[
    {
        date: "2019-1-1", // this is a dupe date
        amount: 20,
        ...
    },
    {
        date: "2019-1-1", // this is a dupe date
        amount: 40,
        ...
    },
    {
        date: "2019-1-2",
        amount: 40,
        ...
    },
    {
        date: "2019-1-3",
        amount: 40,
        ...
    }
]

我希望我的数组看起来像什么:

[
    {
        date: "2019-1-1", // this is now a unique date
        amount: 60,       // and the amount was totaled
        ...
    },
    {
        date: "2019-1-2",
        amount: 40,
        ...
    },
    {
        date: "2019-1-3",
        amount: 40,
        ...
    }
]

3 个答案:

答案 0 :(得分:1)

您可以执行以下操作;

var data = [ { date: "2019-1-1", // this is a dupe date
               amount: 20},
             { date: "2019-1-1", // this is a dupe date
               amount: 40},
             { date: "2019-1-2",
               amount: 40},
             { date: "2019-1-3",
               amount: 40}
           ],
   result = Object.values(data.reduce((r,d) => r[d.date] ? (r[d.date].amount += d.amount, r)
                                                         : (r[d.date] = d, r), {}));
console.log(result);

关于评论,我想我必须为那些可能不熟悉某些ES6功能的人解释一下。

Object.values()是一个Object方法,它返回数组中所有属性值。

因此我们将对象缩减为哈希对象,我们稍后通过Object.values()收集属性。在减少时,我们检查当前检查的对象的date值是否在我们的地图中作为键存在。如果不是,我们创建该密钥并将检查对象插入该关键位置,如果是,则我们将先前插入的对象amount属性增加当前检查的objects金额值。

如果您不想改变原始数据,请将r[d.date] = d更改为r[d.date] = Object.assign({},d)

答案 1 :(得分:1)

使用.reduce通过迭代其属性将数组缩减为对象(或其他任何东西)。您只需要测试以查看累加器中是否已存在匹配date的对象:



const input = [
  {
    date: "2019-1-1", // this is a dupe date
    amount: 20,
    foo: 'bar',
  },
  {
    date: "2019-1-1", // this is a dupe date
    amount: 40,
    foo: 'bar',
  },
  {
    date: "2019-1-2",
    amount: 40,
    foo: 'bar',
  },
  {
    date: "2019-1-3",
    amount: 40,
    foo: 'bar',
  }
];
const output = input.reduce((accum, item) => {
  const { date, amount } = item;
  const foundObj = accum.find(({ date: findDate }) => findDate === date);
  if (foundObj) {
    foundObj.amount += amount;
    return accum;
  }
  accum.push(item);
  return accum;
}, []);
console.log(output);




答案 2 :(得分:0)

我这样做的方法是创建一个以日期为关键字的对象,然后你可以遍历数组并创建一个新的日期属性(如果它不存在)或增加数量(如果存在),然后转换它回到了一个数组:

const items = data.reduce((acc, curr) => {
    if (!acc[curr.date]) {  // basically creating a property with the date as the key and the value is the current object
        acc[curr.date] = { ...curr };
    } else {    // if it exists already, then just increment the amount
        acc[curr.date].amount += curr.amount;
    }
    return acc;
}, {});

const newArray = Object.values(items);  // grab all the values from the object above