JavaScript中的组排序算法

时间:2017-04-16 14:43:21

标签: javascript sorting

快速提问。 我有“list”变量,它看起来像这样:

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' },]

我尝试了不同的排序选项,但不知怎的,我的逻辑每次都按组排序。正如您所看到的,上下文并不重要,因为它在任何地方都是相同的。 appid可以重复,但是assetid总是不同的。

我真的想通过appid对不同组中的这些“资产”进行排序。 例如:

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

如果有人可以帮助我,那就太棒了。我真的无法理解这一点,而且我几乎没有想法。对不起,如果这是一个愚蠢的问题..

4 个答案:

答案 0 :(得分:1)

您可以使用对象作为appid组的引用,并创建一个新对象(如果不存在)。推送具有所需属性的新对象。

此提案在哈希表上使用单个循环和闭包。

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

答案 1 :(得分:1)

可能的解决方案之一。

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

答案 2 :(得分:0)

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

这不是产生想要的,而是一个非常相似的结构:

{
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' },
],
//...
}

所以你可以像这样访问它:

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

appid可以通过解构来删除,但我不认为这是非常必要的。即使您从阵列中复制了一个对象,这样做也无法获取appid ...

答案 3 :(得分:0)

你可以用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>
&#13;
&#13;
&#13;