在 JavaScript 中使用动态 属性 对数组中的所有对象项求和
Sum all object items in array with dynamic property in JavaScript
我有以下数组:
[
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
]
我想添加一个包含数组中类别总和的总行。
示例:
[
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5},
{category: 'Total', 'Apr 2021' : 25, 'Mar 2021' : 23, 'Feb 2021': 30}
]
我尝试使用 Object.keys
遍历所有列。但是,感觉可能有更简单的方法来实现这一点。
计算总行数的最佳方法是什么?
请注意,“2021 年 4 月”、“2021 年 3 月”不是固定的,因此我无法对它们进行硬编码。
Please note that "Apr 2021", "Mar 2021" are not fixed so I won't be
able to hardcode them.
在您的情况下,属性是动态的。您可以通过 2 个步骤尝试此方法:
- 使用
Array#reduce
循环数组的所有对象
- 在每个
object
,你通过迭代 object
对每个属性的值求和,因为动态 属性 像这样
for(const [key, value] of Object.entries(curr)
const array = [
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
];
const total = array.reduce((acc, curr) => {
for(const [key, value] of Object.entries(curr)){
if (key !== 'category') {
acc[key] ??= 0;
acc[key] += value;
}
}
return acc;
}, {});
console.log([...array, {category: "Total", ...total}]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const data = [
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
];
const res = data.reduce((result, item) => {
const keys = Object.keys(item);
keys.forEach(key => {
if (key === 'category') { return; }
result[key] = result[key] ? result[key] + item[key] : item[key];
});
return result;
}, { category: 'Total' });
data.push(res);
console.log(data);
简洁的声明方式:
const input = [
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
]
const totalRow = input.reduce((acc, e) => {
Object.keys(e)
.filter(k => k !== 'category')
.forEach(k => acc[k] ? acc[k] += e[k] : acc[k] = e[k])
return acc
}, {category: 'Total'})
const res = [...input, totalRow]
console.log(res)
我有以下数组:
[
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
]
我想添加一个包含数组中类别总和的总行。
示例:
[
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5},
{category: 'Total', 'Apr 2021' : 25, 'Mar 2021' : 23, 'Feb 2021': 30}
]
我尝试使用 Object.keys
遍历所有列。但是,感觉可能有更简单的方法来实现这一点。
计算总行数的最佳方法是什么?
请注意,“2021 年 4 月”、“2021 年 3 月”不是固定的,因此我无法对它们进行硬编码。
Please note that "Apr 2021", "Mar 2021" are not fixed so I won't be able to hardcode them.
在您的情况下,属性是动态的。您可以通过 2 个步骤尝试此方法:
- 使用
Array#reduce
循环数组的所有对象 - 在每个
object
,你通过迭代object
对每个属性的值求和,因为动态 属性 像这样
for(const [key, value] of Object.entries(curr)
const array = [
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
];
const total = array.reduce((acc, curr) => {
for(const [key, value] of Object.entries(curr)){
if (key !== 'category') {
acc[key] ??= 0;
acc[key] += value;
}
}
return acc;
}, {});
console.log([...array, {category: "Total", ...total}]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const data = [
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
];
const res = data.reduce((result, item) => {
const keys = Object.keys(item);
keys.forEach(key => {
if (key === 'category') { return; }
result[key] = result[key] ? result[key] + item[key] : item[key];
});
return result;
}, { category: 'Total' });
data.push(res);
console.log(data);
简洁的声明方式:
const input = [
{category: 'Category 1', 'Apr 2021' : 10, 'Mar 2021' : 20, 'Feb 2021': 5},
{category: 'Category 2', 'Apr 2021' : 8, 'Mar 2021' : 2, 'Feb 2021': 15},
{category: 'Category 3', 'Apr 2021' : 7, 'Mar 2021' : 1, 'Feb 2021': 5}
]
const totalRow = input.reduce((acc, e) => {
Object.keys(e)
.filter(k => k !== 'category')
.forEach(k => acc[k] ? acc[k] += e[k] : acc[k] = e[k])
return acc
}, {category: 'Total'})
const res = [...input, totalRow]
console.log(res)