整理对象数组中的相同键并对值求和 javascript
collating same keys in object array and summing up the values javascript
这是我的对象数组 -
var items = [{category: "", sum: 687355.25},
{category: "", sum: 526335.4},
{category: "building, general work and whitewashing", sum: 991844},
{category: "Mining and quarrying of non metal minerals", sum: 566317.64},
{category: "wholesale: marble stone for building", sum: 1100391.64},
{category: "heavy building contracting, infrastructure work contractor", sum: 600000},
{category: "building and construction contractor", sum: 829142.67},
{category: "building and construction contractor", sum: 952417},
{category: "building and construction contractor, general", sum: 731128},
{category: "building and construction contractor, general", sum: 708000},
{category: "building and construction contractor, institutions and public buildings", sum: 542540},
{category: "retail: womens clothing stores", sum: 540000},
{category: "retail: gas stations", sum: 567000},
{category: "financing - banks and foreign currency", sum: 700000},
{category: "financing - banks and checks clearing agencies", sum: 526950},
{category: "real estate projects launching", sum: 1084839.77},
{category: "real estate sales, lease and rental", sum: 650000},
{category: "real estate services purchase agents", sum: 1147500},
{category: "real estate development", sum: 534000},
{category: "services: financial services", sum: 735000}]
我想得到这个结果 -
modifiedItems = [{category: "", sum: 1213690.65}
{category: "building, general work and whitewashing", sum: 991844},
{category: "Mining and quarrying of non metal minerals", sum: 566317.64},
{category: "wholesale: marble stone for building", sum: 1100391.64},
{category: "heavy building contracting, infrastructure work contractor", sum: 600000},
{category: "building and construction contractor", sum: 1781559.67}
{category: "building and construction contractor, general", sum: 1439128}
{category: "building and construction contractor, institutions and public buildings", sum: 542540},
{category: "retail: womens clothing stores", sum: 540000},
{category: "retail: gas stations", sum: 567000},
{category: "financing - banks and foreign currency", sum: 700000},
{category: "financing - banks and checks clearing agencies", sum: 526950},
{category: "real estate projects launching", sum: 1084839.77},
{category: "real estate sales, lease and rental", sum: 650000},
{category: "real estate services purchase agents", sum: 1147500},
{category: "real estate development", sum: 534000},
{category: "services: financial services", sum: 735000}]
消除重复的键并对有很多重复项的值求和。我知道我应该使用 reduce,但就是想不通。
请帮忙!
您可以将 Array#reduce 与辅助对象一起使用(示例中的 dict
)。帮助器对象维护对已添加类别的引用。当对象包含新类别时,将其添加到数组和 dict
对象中。如果该对象已存在于 dict
中,则将其总和添加到类别总和中。
var items = [{"category":"","sum":687355.25},{"category":"","sum":526335.4},{"category":"building, general work and whitewashing","sum":991844},{"category":"Mining and quarrying of non metal minerals","sum":566317.64},{"category":"wholesale: marble stone for building","sum":1100391.64},{"category":"heavy building contracting, infrastructure work contractor","sum":600000},{"category":"building and construction contractor","sum":829142.67},{"category":"building and construction contractor","sum":952417},{"category":"building and construction contractor, general","sum":731128},{"category":"building and construction contractor, general","sum":708000},{"category":"building and construction contractor, institutions and public buildings","sum":542540},{"category":"retail: womens clothing stores","sum":540000},{"category":"retail: gas stations","sum":567000},{"category":"financing - banks and foreign currency","sum":700000},{"category":"financing - banks and checks clearing agencies","sum":526950},{"category":"real estate projects launching","sum":1084839.77},{"category":"real estate sales, lease and rental","sum":650000},{"category":"real estate services purchase agents","sum":1147500},{"category":"real estate development","sum":534000},{"category":"services: financial services","sum":735000}];
var dict = Object.create(null); // create an empty object
var result = items.reduce(function(arr, o) {
var current = dict[o.category]; // get the object from dict
if(!current) { // if dict doesn't contain object
current = Object.assign({}, o); // create a clone of the object - this prevents changing the original object
arr.push(current); // push it to the array
dict[o.category] = current; // add it to dict
} else { // if dict contains the object
current.sum += o.sum; // update the sum
}
return arr;
}, []);
console.log(result);
这确实可以使用 reduce 来完成:
results = items.reduce(sumFunction)
最终结果的结构值得一看。在这种情况下,它将是一个对象数组。当它遍历所有项目时,Reduce 将建立(或累积)这个结果。开始累积过程的初始值将是一个空数组。我们将其作为第二个参数传递:
results = items.reduce(sumFunction, []);
但是 sumFunction 怎么写呢?
将使用 3 个参数调用 sumFunction:保存临时结果(= 累加器)的变量、当前项和当前项的索引。累加器会逐渐变得越来越像你想要的最终结果:一个项目数组。
现在我们可以写下每一步传递给累加器时应该发生什么:
function sumFunction (accumulator, currentItem, currentIndex) {
// look up if the current item is of a category that is already in our end result.
index = accumulator.findIndex((item) => item.category === currentItem.category)
if (index < 0) {
accumulator.push(currentItem); // now item added to the array
} else {
accumulator[index].sum += currenItem.sum // update the sum of already existing item
}
return accumulator;
}
或者如果您使用的是 es5:
function sumFunction (accumulator, currentItem, currentIndex) {
// look up if the current item is of a category that is already in our end result.
index = accumulator.findIndex(function(item) { return (item.category === currentItem.category);});
if (index < 0) {
accumulator.push(currentItem); // now item added to the array
} else {
accumulator[index].sum += currenItem.sum // update the sum of already existing item
}
return accumulator;
}
我认为这应该可以解决问题。这就是我现在能想到的。以后想到更好的办法再编辑
var map = {};
var new_items = [];
var length=items.length;
for(var i=0;i<length;i++){
if(items[i]["category"] in map){
map[items[i]["category"]]+=items[i]["sum"];
}
else{
map[items[i]["category"]]=items[i]["sum"];
}
}
for(key in map){
new_items.push({"category":key,"sum":map[key]});
}
基本上我创建了一个类别和总值的映射,然后根据需要使用它来构造一个新数组。
这是我的对象数组 -
var items = [{category: "", sum: 687355.25},
{category: "", sum: 526335.4},
{category: "building, general work and whitewashing", sum: 991844},
{category: "Mining and quarrying of non metal minerals", sum: 566317.64},
{category: "wholesale: marble stone for building", sum: 1100391.64},
{category: "heavy building contracting, infrastructure work contractor", sum: 600000},
{category: "building and construction contractor", sum: 829142.67},
{category: "building and construction contractor", sum: 952417},
{category: "building and construction contractor, general", sum: 731128},
{category: "building and construction contractor, general", sum: 708000},
{category: "building and construction contractor, institutions and public buildings", sum: 542540},
{category: "retail: womens clothing stores", sum: 540000},
{category: "retail: gas stations", sum: 567000},
{category: "financing - banks and foreign currency", sum: 700000},
{category: "financing - banks and checks clearing agencies", sum: 526950},
{category: "real estate projects launching", sum: 1084839.77},
{category: "real estate sales, lease and rental", sum: 650000},
{category: "real estate services purchase agents", sum: 1147500},
{category: "real estate development", sum: 534000},
{category: "services: financial services", sum: 735000}]
我想得到这个结果 -
modifiedItems = [{category: "", sum: 1213690.65}
{category: "building, general work and whitewashing", sum: 991844},
{category: "Mining and quarrying of non metal minerals", sum: 566317.64},
{category: "wholesale: marble stone for building", sum: 1100391.64},
{category: "heavy building contracting, infrastructure work contractor", sum: 600000},
{category: "building and construction contractor", sum: 1781559.67}
{category: "building and construction contractor, general", sum: 1439128}
{category: "building and construction contractor, institutions and public buildings", sum: 542540},
{category: "retail: womens clothing stores", sum: 540000},
{category: "retail: gas stations", sum: 567000},
{category: "financing - banks and foreign currency", sum: 700000},
{category: "financing - banks and checks clearing agencies", sum: 526950},
{category: "real estate projects launching", sum: 1084839.77},
{category: "real estate sales, lease and rental", sum: 650000},
{category: "real estate services purchase agents", sum: 1147500},
{category: "real estate development", sum: 534000},
{category: "services: financial services", sum: 735000}]
消除重复的键并对有很多重复项的值求和。我知道我应该使用 reduce,但就是想不通。 请帮忙!
您可以将 Array#reduce 与辅助对象一起使用(示例中的 dict
)。帮助器对象维护对已添加类别的引用。当对象包含新类别时,将其添加到数组和 dict
对象中。如果该对象已存在于 dict
中,则将其总和添加到类别总和中。
var items = [{"category":"","sum":687355.25},{"category":"","sum":526335.4},{"category":"building, general work and whitewashing","sum":991844},{"category":"Mining and quarrying of non metal minerals","sum":566317.64},{"category":"wholesale: marble stone for building","sum":1100391.64},{"category":"heavy building contracting, infrastructure work contractor","sum":600000},{"category":"building and construction contractor","sum":829142.67},{"category":"building and construction contractor","sum":952417},{"category":"building and construction contractor, general","sum":731128},{"category":"building and construction contractor, general","sum":708000},{"category":"building and construction contractor, institutions and public buildings","sum":542540},{"category":"retail: womens clothing stores","sum":540000},{"category":"retail: gas stations","sum":567000},{"category":"financing - banks and foreign currency","sum":700000},{"category":"financing - banks and checks clearing agencies","sum":526950},{"category":"real estate projects launching","sum":1084839.77},{"category":"real estate sales, lease and rental","sum":650000},{"category":"real estate services purchase agents","sum":1147500},{"category":"real estate development","sum":534000},{"category":"services: financial services","sum":735000}];
var dict = Object.create(null); // create an empty object
var result = items.reduce(function(arr, o) {
var current = dict[o.category]; // get the object from dict
if(!current) { // if dict doesn't contain object
current = Object.assign({}, o); // create a clone of the object - this prevents changing the original object
arr.push(current); // push it to the array
dict[o.category] = current; // add it to dict
} else { // if dict contains the object
current.sum += o.sum; // update the sum
}
return arr;
}, []);
console.log(result);
这确实可以使用 reduce 来完成:
results = items.reduce(sumFunction)
最终结果的结构值得一看。在这种情况下,它将是一个对象数组。当它遍历所有项目时,Reduce 将建立(或累积)这个结果。开始累积过程的初始值将是一个空数组。我们将其作为第二个参数传递:
results = items.reduce(sumFunction, []);
但是 sumFunction 怎么写呢?
将使用 3 个参数调用 sumFunction:保存临时结果(= 累加器)的变量、当前项和当前项的索引。累加器会逐渐变得越来越像你想要的最终结果:一个项目数组。
现在我们可以写下每一步传递给累加器时应该发生什么:
function sumFunction (accumulator, currentItem, currentIndex) {
// look up if the current item is of a category that is already in our end result.
index = accumulator.findIndex((item) => item.category === currentItem.category)
if (index < 0) {
accumulator.push(currentItem); // now item added to the array
} else {
accumulator[index].sum += currenItem.sum // update the sum of already existing item
}
return accumulator;
}
或者如果您使用的是 es5:
function sumFunction (accumulator, currentItem, currentIndex) {
// look up if the current item is of a category that is already in our end result.
index = accumulator.findIndex(function(item) { return (item.category === currentItem.category);});
if (index < 0) {
accumulator.push(currentItem); // now item added to the array
} else {
accumulator[index].sum += currenItem.sum // update the sum of already existing item
}
return accumulator;
}
我认为这应该可以解决问题。这就是我现在能想到的。以后想到更好的办法再编辑
var map = {};
var new_items = [];
var length=items.length;
for(var i=0;i<length;i++){
if(items[i]["category"] in map){
map[items[i]["category"]]+=items[i]["sum"];
}
else{
map[items[i]["category"]]=items[i]["sum"];
}
}
for(key in map){
new_items.push({"category":key,"sum":map[key]});
}
基本上我创建了一个类别和总值的映射,然后根据需要使用它来构造一个新数组。