JS:如何通过其值总结对象数组

时间:2019-12-13 09:50:57

标签: javascript arrays object

let arrayFirst = [{name: 'a', num: 1}, { name: 'b', num: 1} ]
let arraySecond = [{name: 'a', num: 1}, { name: 'b', num: 1} ]
let arrayThid = [{name: 'a', num: 1}, { name: 'c', num: 1} ]

... ... ...

预期输出:

[{name: 'a', num: 3}, { name: 'b', num: 2}, { name: 'c', num: 1} ]

我只发现数组内部对象求和,但是如何通过对象的键值求和呢?

7 个答案:

答案 0 :(得分:2)

您可以使用下面的函数对值进行分组和求和。该方法可以根据需要获取任意数量的数组(或对象),并根据groupby(您的情况下的名称)和sumkey对其求和

function sumArrays(groupby, sumkey, ...arrays) {
  return [...arrays.flat().reduce((a, b) => a.set(b[groupby], (a.get(b[groupby]) || 0) + b[sumkey]), new Map())].map(([k, v]) => ({
    [groupby]: k,
    [sumkey]: v
  }))
}

console.log(sumArrays('name', 'num', arrayFirst, arraySecond, arrayThid));
<script>
arrayFirst = [{
  name: 'a',
  num: 1
}, {
  name: 'b',
  num: 1
}]
let arraySecond = [{
  name: 'a',
  num: 1
}, {
  name: 'b',
  num: 1
}]
let arrayThid = [{
  name: 'a',
  num: 1
}, {
  name: 'c',
  num: 1
}]
</script>

答案 1 :(得分:0)

let arrayFirst = [{ name: 'a', num: 1 }, { name: 'b', num: 1 }]
let arraySecond = [{ name: 'a', num: 1 }, { name: 'b', num: 1 }]
let arrayThid = [{ name: 'a', num: 1 }, { name: 'c', num: 1 }]

// [{name: 'a', num: 3}, { name: 'b', num: 2}, { name: 'c', num: 1} ]
var r = {}

addObject = (arrayObj) => {
    arrayObj.forEach(first => {
        if (r[first.name] == null) r[first.name] = 0;
        r[first.name] += first.num
    })
}

addObject(arrayFirst)
addObject(arraySecond)
addObject(arrayThid)

console.log(r)
var result = []

Object.keys(r).forEach(key => {
    result.push({ name: key, num: r[key] })
});

答案 2 :(得分:0)

您可以借助Array.concatfindIndex来完成:

let arrayFirst = [{
    name: 'a',
    num: 1
}, {
    name: 'b',
    num: 1
}]
let arraySecond = [{
    name: 'a',
    num: 1
}, {
    name: 'b',
    num: 1
}]
let arrayThid = [{
    name: 'a',
    num: 1
}, {
    name: 'c',
    num: 1
}]

var result = [];

arrayThid.concat((arrayFirst.concat(arraySecond))).forEach(function(obj) {
    let index = result.findIndex(x => x.name === obj.name);
    if (index == -1) {
        result.push(obj);
    } else {
        result[index].num += obj.num;
    }
});

console.log(result)

答案 3 :(得分:0)

您可以使用reduce方法:

const result = arrayFirst.concat(arraySecond).concat(arrayThid).reduce((a, c) => {
  a[c.name] = a[c.name] || {name: c.name, num: 0};
  a[c.name].num += c.num;
  return a;
}, {});

一个例子:

let arrayFirst = [{name: 'a', num: 1}, { name: 'b', num: 1} ]
let arraySecond = [{name: 'a', num: 1}, { name: 'b', num: 1} ]
let arrayThid = [{name: 'a', num: 1}, { name: 'c', num: 1} ]

const result = arrayFirst.concat(arraySecond).concat(arrayThid).reduce((a, c) => {
  a[c.name] = a[c.name] || {name: c.name, num: 0};
  a[c.name].num += c.num;
  return a;
}, {});

console.log(Object.values(result));

答案 4 :(得分:0)

在我看来,@ baao的答案很棒而且通用。但是,如果您想要更简单的方法,请尝试:

[arrayFirst, arraySecond, arrayThird].flat().filter((item, index, array) => array.findIndex(i => (i.name === item.name)) === index)

或者如果您要检查数组中的整个对象,则可以使用

[arrayFirst, arraySecond, arrayThird].flat().filter((item, index, array) => array.findIndex(i => (JSON.stringify(i) === JSON.stringify(item))) === index)

答案 5 :(得分:0)

此外,您可以将结果缓存在对象中:

const addSumToCachedNum = (acc, item) => {
    const { name, num } = item;
    const current = acc[name] || {};
    const currentNum = current.num || 0;

    acc[name] = {
      name,
      num: currentNum + num,
    };

    return acc;
}

const sumArrayByKey = (...items) => {
    const mergedArray = [].concat(...items);
    const sumObject = mergedArray.reduce(addSumToCachedNum, {});

    return Object.values(sumObject);
};

答案 6 :(得分:0)

您可以使用函数reduce对值进行分组,并使用函数Object.values将分组后的值提取为数组。

let arrayFirst = [{name: 'a', num: 1}, { name: 'b', num: 1} ];
let arraySecond = [{name: 'a', num: 1}, { name: 'b', num: 1} ];
let arrayThid = [{name: 'a', num: 1}, { name: 'c', num: 1} ];

let result = Object.values(arrayFirst.concat(arraySecond).concat(arrayThid).reduce((a, {name, num}) => {
  (a[name] || (a[name] = {name, num: 0})).num += num;
  return a;
}, Object.create(null)));

console.log(result);