整理对象数组中的相同键并总结值javascript

时间:2017-07-23 06:50:38

标签: javascript arrays object reduce

这是我的对象数组 -



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,但是无法弄明白。 请帮忙!

3 个答案:

答案 0 :(得分:1)

您可以将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);

答案 1 :(得分:1)

确实可以使用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;
}

答案 2 :(得分:0)

我认为这应该可以解决问题。这就是我现在能想到的。如果我想到更好的方法,我会在之后编辑它。

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]});
   }

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