在javascript中按多个对象属性对数组排序

在javascript中按多个对象属性对数组排序,javascript,arrays,sorting,Javascript,Arrays,Sorting,我想按checked和type.id对数组进行排序。我在使用下面的排序代码,但是“type.id”似乎有问题,因为我的列表没有按选中的分类 var array = [ { "checked": true, "name":"Name", "type": { "id": 1, "tag": "tag" } }, { "checked": true,

我想按checked和type.id对数组进行排序。我在使用下面的排序代码,但是“type.id”似乎有问题,因为我的列表没有按选中的分类

var array  = [
    {
        "checked": true,
        "name":"Name",
        "type": {
            "id": 1,
            "tag": "tag"
        }
    },
    {
        "checked": true,
        "name":"Name",
        "type": {
            "id": 3,
            "tag": "tag"
        }
    },
    {
        "checked": false,
        "name":"Name",
        "type": {
            "id": 2,
            "tag": "tag"
        }
    },
];
关于如何对类型对象进行排序有什么想法吗


(我还没有找到另一个问题的答案,这个问题的答案是通用分拣机能够根据数组中的对象进行排序)

在数组中重载
排序
方法,然后您可以根据排序条件切换
。注意:我删除了
返回0,如果它们在第一次排序中相等,则返回0,以便在
选中的
值相等时移动到第二次排序

var数组=[
{
“检查”:正确,
“名称”:“名称”,
“类型”:{
“id”:1,
“标签”:“标签”
}
},
{
“检查”:正确,
“名称”:“名称”,
“类型”:{
“id”:3,
“标签”:“标签”
}
},
{
“checked”:false,
“名称”:“名称”,
“类型”:{
“id”:2,
“标签”:“标签”
}
},
];
功能自定义排序(ob1、ob2){
如果(ob1.checked>ob2.checked){
返回1;
}如果(ob1.checkedob2.type.id){
返回1
}否则{
返回0;
}
}
console.log(数组);

log(array.sort(customSort))这里是一个使用组合排序的通用解决方案,您可以将任意数量的排序条件组合成一个大型排序函数:

函数到\u元组(元素数组){
返回_元素的数组_.map((元素,索引)=>[element,index]);
}
函数到元素(元组数组){
返回数组_,数组为_tuples.map((element)=>element[0]);
}
函数组合\排序(排序\函数){
常量默认排序=(l,r)=>l[1]{
const mixin=(下一次排序,左,右)=>{
常量结果=排序函数(左、右);
返回结果===0?下一次_排序(左、右):结果;
}
返回mixin.bind(null,master_sort);
},默认排序);
}
函数排序\u检查\u到\u顶部(左\u元组、右\u元组){
const left=左元组[0];
const right=right_元组[0];
if(left.checked!==right.checked){
向左返回。检查?-1:1;
}
返回0;
}
函数排序从下到上(左、右){
const left=左元组[0];
const right=right_元组[0];
if(left.type.id!==right.type.id){
返回left.type.id>right.type.id?1:-1;
}
返回0;
}
常量主排序=合成排序([
排序\u检查\u到\u顶部,
将\u下\u id\u排序到\u上,
]);
变量数组=[
{
“检查”:正确,
“名称”:“名称”,
“类型”:{
“id”:1,
“标签”:“标签”
}
},
{
“checked”:false,
“名称”:“名称”,
“类型”:{
“id”:25,
“标签”:“标签”
}
},
{
“检查”:正确,
“名称”:“名称”,
“类型”:{
“id”:3,
“标签”:“标签”
}
},
{
“checked”:false,
“名称”:“名称”,
“类型”:{
“id”:2,
“标签”:“标签”
}
},
];
const result=to_元素(to_元组(数组).sort(master_sort));
控制台日志(结果);

您可以对嵌套属性使用嵌套方法,并使用一个函数数组来比较值

函数排序优先级(数组、键、fn){
函数getValue(o,k){
返回k.split('..)。reduce((p,l)=>(p |{})[l],o);
}
返回数组.sort((a,b)=>{
变量d;
一些((k,i)=>d=fn[i](getValue(a,k),getValue(b,k));
返回d;
});
}
var数组=[{checked:false,name:“name”,type:{id:2,tag:“tag”},{checked:true,name:“name”,type:{id:3,tag:“tag”},{checked:true,name:“name”,type:{id:1,tag:“tag”}];
排序优先级(数组,['checked',type.id'],[(a,b)=>b-a,(a,b)=>a-b]);
console.log(数组)

.as控制台包装{max height:100%!important;top:0;}
是否应
checked=true
作为第一个?根据其
选中的
分隔数组。然后根据它们的
type.id
对这两个数组进行排序。完成后,只需按照选中的
排序顺序将排序后的数组相互追加。这只是一个想法:难道不可能使用稳定的排序算法进行优先级排序吗?先按最低优先级排序,然后再按最高优先级排序?Lodash可能是@Distjubo的有用副本JavaScript
.sort()
方法明确不要求是稳定的,因为它通常是一个快速排序实现,所以通常不稳定。“sunction”数组?注意:您可以使用
array.sort((a,b)=>keys.map((k,i)=>fn[i](getValue(a,k),getValue(b,k))。查找(d=>d!=0))
以避免临时变量和副作用。忽略这一点,
array.sort((a,b)=>keys.reduce((d,k,i)=>d | | fn[i](getValue(a,k),getValue(b,k)),0))
更好,因为它保留了短路(我们仍然需要循环所有键,但一旦找到值,它就不起作用)。
sortByPriority(array, ['checked', 'type.id']);

sortByPriority(data, priorities) {
    if (priorities.length == 0 || data.length == 0) {
        return data;
    }
    const nextPriority = priorities[0];
    const remainingPriorities = priorities.slice(1);
    const matched = data.filter(item => item.hasOwnProperty(nextPriority));
    const remainingData = data.filter(item => !item.hasOwnProperty(nextPriority));

    return this.sortByPriority(matched, remainingPriorities)
        .sort((a, b) => (a[nextPriority] > b[nextPriority]) ? 1 : -1)
        .concat(this.sortByPriority(remainingData, remainingPriorities));
}