【问题标题】:how to group objects in an array如何对数组中的对象进行分组
【发布时间】:2017-08-18 05:43:32
【问题描述】:

我有一个对象数组,我想根据两个键对其对象进行分组

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 循环不起作用,并且由于连续循环执行而导致我的系统挂起。

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

【问题讨论】:

  • 哦...谢谢@Teemu
  • 如果final 数组开始为空,for(var j = 0; j &lt; final.length; j++) 将如何工作?
  • 那么,在这种情况下该怎么办? @非破坏性
  • 我应该在for(var j = 0; j &lt; final.length; j++)之前做if(final.length === 0){final.push(obj)}吗???

标签: javascript arrays object grouping


【解决方案1】:

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

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)

注意

【讨论】:

    【解决方案2】:

    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】:

      这是一个使用 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;}

      【讨论】:

        【解决方案4】:

        您可以通过 id 构建地图,并将所有 creduce 累加。 类似的东西:

        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)

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:
            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;
             }, []);
            

            【讨论】:

              【解决方案7】:
              1. obj[属性] eq undifined

                var obj = {name:'John'};
                console.log(obj[name]);
              2. if((obj.name !== final[j].name) || (obj[id] !== final[j].id)){
                    // 推
                }别的{
                    // 代码
                }

              【讨论】:

                猜你喜欢
                • 2020-11-23
                • 2018-05-01
                • 2021-09-12
                • 1970-01-01
                • 2019-05-29
                • 1970-01-01
                • 2019-11-20
                • 2021-11-25
                • 2021-03-30
                相关资源
                最近更新 更多