Javascript 按属性对数组项排序并保持原始数组的顺序

Javascript 按属性对数组项排序并保持原始数组的顺序,javascript,arrays,sorting,grouping,Javascript,Arrays,Sorting,Grouping,我编写此函数是为了按一个或多个属性对数组进行分组: var groupBy = function (fields, data) { var groups = {}; for (var i = 0; i < data.length; i++) { var item = data[i]; var container = groups; for (var j = 0; j < fields.length; j++) {

我编写此函数是为了按一个或多个属性对数组进行分组:

var groupBy = function (fields, data) {
    var groups = {};
    for (var i = 0; i < data.length; i++) {
        var item = data[i];
        var container = groups;
        for (var j = 0; j < fields.length; j++) {
            var groupField = fields[j];
            var groupName = item[groupField];
            if (!container[groupName]) {
                container[groupName] = j < fields.length - 1 ? {} : [];
            }
            container = container[groupName];
        }
        container.push(item);
    }
    return groups;
};
我得到这个输出:

{
    "cat": [
        {
            "type": "cat",
            "name": "Max"
        },
        {
            "type": "cat",
            "name": "Zoe"
        },
        {
            "type": "cat",
            "name": "Molly"
        }
    ],
    "dog": [
        {
            "type": "dog",
            "name": "Charlie"
        },
        {
            "type": "dog",
            "name": "Abby"
        }
    ]
}
到目前为止一切正常。。。问题是我需要这些键来反映原始输入数组的顺序。因此,如果第一个项目是一只猫,我迭代组键,我需要第一个键也是猫。因为JS中的对象没有明确的顺序,所以我不能保证正确的顺序。我怎样才能做到这一点


编辑:

我想结果应该是这样的:

groupBy(["type", "name"], animals)
应产生:

[
  {
    "group": "cat",
    "items": [
      {
        "group": "max",
        "items": [
          {
            "type": "cat",
            "name": "Max"
          }
        ]
      },
      {
        "group": "Zoe",
        "items": [
          {
            "type": "cat",
            "name": "Zoe"
          }
        ]
      },
      {
        "group": "Molly",
        "items": [
          {
            "type": "cat",
            "name": "Molly"
          }
        ]
      }
    ]
  },
  {
    "group": "dog",
    "items": [
      {
        "group": "Charlie",
        "items": [
          {
            "type": "dog",
            "name": "Charlie"
          }
        ]
      },
      {
        "group": "Abby",
        "items": [
          {
            "type": "dog",
            "name": "Abby"
          }
        ]
      }
    ]
  }
]

您可以将结果数据结构更改为数组数组,以便保持秩序

var动物=[
{键入:“cat”,名称:“Max”},
{类型:“狗”,名称:“查理”},
{键入:“猫”,名称:“佐伊”},
{键入:“dog”,名称:“Abby”},
{键入:“猫”,名称:“莫莉”}
];
var结果=[]
动物。forEach(功能(e){
如果(!此[e.type]){
此[e.type]=[e.type,[]
结果.推送(此[e.type])
}
此[e.type][1]。推送(e)
}, {})

console.log(result)
您可以稍微更改您的函数,以便它在每个组级别添加一个特殊属性,该属性按键的迭代顺序列出键:

var groupBy=函数(字段、数据){
变量组={u键:[]};
//             ^^^^^^^^^
对于(变量i=0;i

。作为控制台包装{max height:100%!important;top:0;}
您可以使用一个完全动态的函数对各种键和深度进行分组

此方案使用哈希表和每一级别的数组

函数分组依据(键、数组){
var结果=[];
array.forEach(函数(a){
键。减少(功能(r,k){
如果(!r[a[k]]){
r[a[k]={{}:[]};
r、 _u.push({组:a[k],项:r[a[k].});
}
返回r[a[k]];
}推(a);
},{结果});
返回结果;
}
动物变量=[{type:“cat”,name:“Max”},{type:“dog”,name:“Charlie”},{type:“cat”,name:“Zoe”},{type:“dog”,name:“Abby”},{type:“cat”,name:“Molly”}];
log(groupBy([“type”,“name”],animals));
log(groupBy([“type”],animals))

。作为控制台包装{max height:100%!important;top:0;}
您不能这样做,您需要一个数组以某种特定顺序保存其内容。您可以通过操纵
对象返回的数组来创建迭代顺序。但是,键
。映射不保留插入顺序吗?如果你在这里使用地图而不是普通的旧对象,那可能会得到你想要的?我不能使用地图。。。仅限ES5:/@Teemu:在ES2015及以上版本中,对象属性具有顺序。但是使用它通常不是一个好主意。请添加想要的结果。谢谢,但我需要它来处理多个组属性,例如,
groupBy([“type”,“name]”,animals)。。。据我所知,这种方法只适用于单一级别的分组(?)按多个字段分组的预期结果是什么?我添加了一个示例作为答案。
[
  {
    "group": "cat",
    "items": [
      {
        "group": "max",
        "items": [
          {
            "type": "cat",
            "name": "Max"
          }
        ]
      },
      {
        "group": "Zoe",
        "items": [
          {
            "type": "cat",
            "name": "Zoe"
          }
        ]
      },
      {
        "group": "Molly",
        "items": [
          {
            "type": "cat",
            "name": "Molly"
          }
        ]
      }
    ]
  },
  {
    "group": "dog",
    "items": [
      {
        "group": "Charlie",
        "items": [
          {
            "type": "dog",
            "name": "Charlie"
          }
        ]
      },
      {
        "group": "Abby",
        "items": [
          {
            "type": "dog",
            "name": "Abby"
          }
        ]
      }
    ]
  }
]