如何对数组中的对象进行分组

时间:2017-08-18 05:43:33

标签: javascript arrays object grouping

我有一个对象数组,我想根据两个键

对其对象进行分组
var arr = [ 
  {"name": "apple", "id": "apple_0","c":'20'}, 
  {"name": "dog",   "id": "dog_1","c":'10'}, 
  {"name": "apple", "id": "apple_0","c":'30'},
  {"name": "dog",   "id": "dog_1","c":'10'},
];

我希望结果为

var final = [ 
  {"name": "apple", "id": "apple_0","c":'50'}, 
  {"name": "dog",   "id": "dog_1","c":'20'}
];

场景是这样的 - 我想基于nameid对对象进行分组。如果在最终数组中找到nameid,则将其c加起来。

我试过了:

var final = [];
for(var i = 0; i<arr.length; i++){
    var obj = {};
    obj = arr[i];
    for(var j = 0; j<final.length; j++){
        if((obj[name] !== final[j].name) && (obj[id] !== final[j].id)){
          final.push(obj)
        }else{
            //addition of key `c` in existing object in `final` array 
        }
    }
} 

但是内部for循环不起作用,并且由于连续循环执行而挂起我的系统。

请让我知道如何修复它或任何其他逻辑以获得最终结果。

7 个答案:

答案 0 :(得分:3)

以下是使用hash table#reduce()函数的解决方案 - 请参阅下面的演示:

var arr = [{"name": "apple", "id": "apple_0","c":'20'},{"name": "dog",   "id": "dog_1","c":'10'}, {"name": "apple", "id": "apple_0","c":'30'},{"name": "dog",   "id": "dog_1","c":'10'}];

var result = arr.reduce(function(hash){
  return function(p,c){
    if(hash[c.id])
      hash[c.id].c = +hash[c.id].c + +c.c
    else {
      hash[c.id] = hash[c.id] || c;
      p.push(hash[c.id]);
    }
    return p;
  }
}(Object.create(null)), []);

console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}

答案 1 :(得分:1)

您可以按ID构建地图,并使用c累积所有reduce。 这样的事情:

var arr = [{
    "name": "apple",
    "id": "apple_0",
    "c": '20'
  },
  {
    "name": "dog",
    "id": "dog_1",
    "c": '10'
  },
  {
    "name": "apple",
    "id": "apple_0",
    "c": '30'
  },
  {
    "name": "dog",
    "id": "dog_1",
    "c": '10'
  },
];

var mapResult = arr.reduce((acc, item) => {
  item = {...item}; //clone the item
  item.c = parseInt(item.c, 10);

  if (acc[item.id]) {
    acc[item.id].c += item.c
  } else {
    acc[item.id] = item;
  }

  return acc;
}, {});

const result = Object.keys(mapResult).map((key) => mapResult[key]);

console.log(result)

答案 2 :(得分:1)

var arr = [ 
  {"name": "apple", "id": "apple_0","c":'20'}, 
  {"name": "dog",   "id": "dog_1","c":'10'}, 
  {"name": "apple", "id": "apple_0","c":'30'},
  {"name": "dog",   "id": "dog_1","c":'10'},
];


var final = arr.reduce((acc, cur) => {
  var doPush = true;
  acc.map(v => {
    if (v.name === cur.name) {
      v.c = +v.c + +cur.c
      doPush = false;
    }
  });
  if (doPush) {
    acc.push(cur)
  }
  return acc;
}, []);

console.log (final)

答案 3 :(得分:1)

使用Array.prototype.reduce()Object.keys()函数:

&#13;
&#13;
var arr = [ 
  {"name": "apple", "id": "apple_0","c":'20'}, 
  {"name": "dog",   "id": "dog_1","c":'10'}, 
  {"name": "apple", "id": "apple_0","c":'30'},
  {"name": "dog",   "id": "dog_1","c":'10'},
],
    groups = arr.reduce(function(r, o){
        var k = o.name +'|'+ o.id;
        (r[k])? r[k] += +o.c : r[k] = +o.c;
        return r;
    }, {}),
    result = Object.keys(groups).map(function(k){ 
        var keys = k.split('|'); 
        return {name: keys[0], id: keys[1], c: groups[k]}; 
     });
    
console.log(result);
&#13;
&#13;
&#13;

答案 4 :(得分:1)

您实际上可以使用forEach并在创建新数组之前将元素添加到对象

&#13;
&#13;
var arr = [{
    "name": "apple",
    "id": "apple_0",
    "c": '20'
  },
  {
    "name": "dog",
    "id": "dog_1",
    "c": '10'
  },
  {
    "name": "apple",
    "id": "apple_0",
    "c": '30'
  },
  {
    "name": "dog",
    "id": "dog_1",
    "c": '10'
  },
];
// a new array which be created with updated value
var grouped = [];
arr.forEach(function(a) {
  // check if the element is present
  // if not then add the element
  if (!this[a.id]) {
    this[a.id] = {
      name: a.name,
      id: a.id,
      c: a.c
    };
    grouped.push(this[a.id]);
  } else {
    // if present then add the value of
    this[a.id].c += +a.c;
    
  }
}, Object.create(null));
console.log(grouped)
&#13;
&#13;
&#13;

请注意

答案 5 :(得分:0)

  1. obj [attribuate] eq undifined

    var obj = {name:'John'};
    console.log(obj[name]);
  2. if((obj.name !== final[j].name) || (obj[id] !== final[j].id)){
        // push
    }else{
        // code
    }

答案 6 :(得分:0)

var arr = [ 
  {"name": "apple", "id": "apple_0","c":'20'}, 
  {"name": "dog",   "id": "dog_1","c":'10'}, 
  {"name": "apple", "id": "apple_0","c":'30'},
  {"name": "dog",   "id": "dog_1","c":'10'},
];


  arr.reduce(function(cumm, current) {
     var indexNum = cumm.findIndex(x =>{
          return x.name == current.name;
     });      
  if(indexNum > -1) {
    cumm[indexNum].c =  Number(cumm[indexNum].c) + Number(current.c);
  } else {
    cumm.push(current);
  }
   return cumm;
 }, []);