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"
}
]
}
]
}
]