整理对象数组中的相同键并对值求和 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]});
   }

基本上我创建了一个类别和总值的映射,然后根据需要使用它来构造一个新数组。