1

Quick question. I have the "list" variable and it looks like this:

var list = [ { appid: '753', contextid: '6', assetid: '3351193666' },
  { appid: '255710', contextid: '6', assetid: '4141511622' },
  { appid: '255710', contextid: '6', assetid: '4356835667' },
  { appid: '255710', contextid: '6', assetid: '4145011657' },
  { appid: '255710', contextid: '6', assetid: '4356835665' },
  { appid: '255710', contextid: '6', assetid: '4356835666' },
  { appid: '730', contextid: '6', assetid: '4356832195' },
  { appid: '730', contextid: '6', assetid: '4356832197' },
  { appid: '730', contextid: '6', assetid: '4356832196' },
  { appid: '321040', contextid: '6', assetid: '3682654698' },
  { appid: '321040', contextid: '6', assetid: '3542604179' },
  { appid: '322330', contextid: '6', assetid: '3498901747' },
  { appid: '322330', contextid: '6', assetid: '3903574578' },]

I tried different sorting options, but somehow my logic fails every time to sort them by groups. As you can see, the contextid is not important since it is the same everywhere. The appid can repeat itself but the assetid is always different.

I would really like to sort these "assets" in different groups by appid. For example:

var groups = [{appid: '753', assets: [{contextid: '6', assetid: '3351193666'}]},
              {appid: '255710', assets: [{contextid: '6', assetid: '4141511622'}, {contextid: '6', appid: '4356835667'}, {contextid: '6', appid: '4145011657'}]}
              ....];

If someone could help me, that'd be extremely great. I really can't grasp my mind around this, and I've pretty much ran out of ideas. Sorry if it's a dumb question..

Brian Briu
  • 45
  • 5
  • Possible duplicate of [What is the most efficient method to groupby on a javascript array of objects?](http://stackoverflow.com/questions/14446511/what-is-the-most-efficient-method-to-groupby-on-a-javascript-array-of-objects) – Andreas Apr 16 '17 at 14:46

4 Answers4

0
var newlist=list.reduce(function(newlist,el){
  return (newlist[el.appid]=newlist[el.appid]||[]).push(el),newlist;
},{});

This produces not the wanted, but a quite simillar structure:

{
255710:[
    { appid: '255710', contextid: '6', assetid: '4141511622' },
    { appid: '255710', contextid: '6', assetid: '4356835667' },
    { appid: '255710', contextid: '6', assetid: '4145011657' },
    { appid: '255710', contextid: '6', assetid: '4356835665' },
    { appid: '255710', contextid: '6', assetid: '4356835666' },
],
//...
}

So you can access it like this:

console.log(newlist[255710]);//all els with appid 255710

The appid could be removed trough destructuring, but i dont think that this is really necessary. Not doing so enables you to get the appid even if you copy one object out of the array...

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

You could use an object as reference to appid group and create a new object, if not exists. The push new object with the wanted properties.

This proposal uses a single loop and a closure over a hash table.

var list = [{ appid: '753', contextid: '6', assetid: '3351193666' }, { appid: '255710', contextid: '6', assetid: '4141511622' }, { appid: '255710', contextid: '6', assetid: '4356835667' }, { appid: '255710', contextid: '6', assetid: '4145011657' }, { appid: '255710', contextid: '6', assetid: '4356835665' }, { appid: '255710', contextid: '6', assetid: '4356835666' }, { appid: '730', contextid: '6', assetid: '4356832195' }, { appid: '730', contextid: '6', assetid: '4356832197' }, { appid: '730', contextid: '6', assetid: '4356832196' }, { appid: '321040', contextid: '6', assetid: '3682654698' }, { appid: '321040', contextid: '6', assetid: '3542604179' }, { appid: '322330', contextid: '6', assetid: '3498901747' }, { appid: '322330', contextid: '6', assetid: '3903574578' }],
    groups = list.reduce(function (hash) {
        return function (r, a) {
            if (!hash[a.appid]) {
                hash[a.appid] = { appid: a.appid, assets: [] };
                r.push(hash[a.appid]);
            }
            hash[a.appid].assets.push({ contextid: a.contextid, assetid: a.assetid });
            return r;
        };
    }(Object.create(null)), []);

console.log(groups);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

One of the possible solutions.

var list = [{ appid: '753', contextid: '6', assetid: '3351193666' }, { appid: '255710', contextid: '6', assetid: '4141511622' }, { appid: '255710', contextid: '6', assetid: '4356835667' }, { appid: '255710', contextid: '6', assetid: '4145011657' }, { appid: '255710', contextid: '6', assetid: '4356835665' }, { appid: '255710', contextid: '6', assetid: '4356835666' }, { appid: '730', contextid: '6', assetid: '4356832195' }, { appid: '730', contextid: '6', assetid: '4356832197' }, { appid: '730', contextid: '6', assetid: '4356832196' }, { appid: '321040', contextid: '6', assetid: '3682654698' }, { appid: '321040', contextid: '6', assetid: '3542604179' }, { appid: '322330', contextid: '6', assetid: '3498901747' }, { appid: '322330', contextid: '6', assetid: '3903574578' }], obj = {};

    list.forEach(function(v) {
      (obj[v.appid] || (obj[v.appid] = [])).push({contextid: v.contextid, assetid: v.assetid});
    });
    var res = Object.keys(obj).map(v => Object.assign({}, {appid: v, assets: obj[v]}));
  
    console.log(res);
kind user
  • 40,029
  • 7
  • 67
  • 77
0

You can do this with lodash :

var list = [ { appid: '753', contextid: '6', assetid: '3351193666' },
  { appid: '255710', contextid: '6', assetid: '4141511622' },
  { appid: '255710', contextid: '6', assetid: '4356835667' },
  { appid: '255710', contextid: '6', assetid: '4145011657' },
  { appid: '255710', contextid: '6', assetid: '4356835665' },
  { appid: '255710', contextid: '6', assetid: '4356835666' },
  { appid: '730', contextid: '6', assetid: '4356832195' },
  { appid: '730', contextid: '6', assetid: '4356832197' },
  { appid: '730', contextid: '6', assetid: '4356832196' },
  { appid: '321040', contextid: '6', assetid: '3682654698' },
  { appid: '321040', contextid: '6', assetid: '3542604179' },
  { appid: '322330', contextid: '6', assetid: '3498901747' },
  { appid: '322330', contextid: '6', assetid: '3903574578' },]

var newList = [];
_.each(list, function(item){
  var index =_.findIndex(newList, {'appid' : item.appid });
  if(index == -1)
    newList.push({ appid: item.appid, assets : [ 
      _.omit( item , ['appid'])]});
  else newList[index].assets.push(_.omit( item , ['appid']))
  });
  
  console.log(newList);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
anshulk
  • 458
  • 5
  • 13