对象数组的复合排序(排序)

Compound sorting(ordering) of object array

本文关键字:排序 复合 数组 对象      更新时间:2023-09-26

我有一个类似于下面列出的设计对象数组。我想先按ClassName(按字母顺序)排序这个数组,然后按StartDate排序,但我想保留初始排序。我知道我可能会使用sort()来完成这一点,但我不确定如何在不将原始数组分解为更小的组的情况下保留初始排序。

var objArray = [
    {
        ClassName: "Excel",
        Location: "Kansas City",
        StartDate: "2/1/2016",
        EndDate: "6/2/2016,"
    },
    {
        ClassName: "Outlook",
        Location: "Kansas City",
        StartDate: "1/1/2016",
        EndDate: "5/2/2016,"
    },
    {
        ClassName: "Excel",
        Location: "Kansas City",
        StartDate: "3/1/2016",
        EndDate: "7/2/2016,"
    }
];

理想情况下,根据上面的数据,我最终会得到这样的东西:

var objArray = [
    {
        ClassName: "Excel",
        Location: "Kansas City",
        StartDate: "2/1/2016",
        EndDate: "6/2/2016,"
    },
    {
        ClassName: "Excel",
        Location: "Kansas City",
        StartDate: "3/1/2016",
        EndDate: "7/2/2016,"
    },
    {
        ClassName: "Outlook",
        Location: "Kansas City",
        StartDate: "1/1/2016",
        EndDate: "5/2/2016,"
    }
];

,为了清楚起见,如果有多个类,最终排序将看起来像这样:

Excel (1/1/2016)
Excel (1/2/2016)
Excel (2/3/2016)
Outlook (1/3/2016)
Outlook (2/3/2016)
Word (1/1/2016)
Word (5/5/2016)

@emed指向的链接有一个有趣的解决方案。

我唯一的问题是性能,因为他在比较函数中不断地做map和reduce。

所以我做了一个稍微修改的版本,我也保留了反向排序的能力。

var objArray = [
    {
        ClassName: "Excel",
        Location: "Kansas City",
        StartDate: "2/1/2016",
        EndDate: "6/2/2016,"
    },
    {
        ClassName: "Outlook",
        Location: "Kansas City",
        StartDate: "1/1/2016",
        EndDate: "5/2/2016,"
    },
    {
        ClassName: "Excel",
        Location: "Kansas City",
        StartDate: "3/1/2016",
        EndDate: "7/2/2016,"
    }
];
objArray.sort(fieldSorter(['ClassName', 'StartDate']));
console.log(objArray);
function fieldSorter(fields) {
    var maps = [];
    fields.map(function (o) {
       var dir = +1;
       if (o[0] === '-') {
          dir = -1;
          o=o.substring(1);
       }
       maps.push({fn:o, dir:dir});
    });
    return function (a, b) {
       var ret = 0;
       maps.some(function (o) {
         if (a[o.fn] > b[o.fn]) ret = o.dir;
         else if (a[o.fn] < b[o.fn]) ret = -o.dir;
         else ret = 0;
         return ret !== 0;
       });
       return ret;
    };
}

供将来参考:这是我最终用来解决问题的函数。谢谢大家的意见:

function fieldSorter(fields) {
    return function (a, b) {
        return fields
            .map(function (o) {
                var dir = 1;
                if (o[0] === '-') {
                   dir = -1;
                   o=o.substring(1);
                }
                if (a[o] > b[o]) return dir;
                if (a[o] < b[o]) return -(dir);
                return 0;
            })
            .reduce(function firstNonZeroValue (p,n) {
                return p ? p : n;
            }, 0);
    };
}

array.sort()在您面临问题的地方工作得很好。

console.log (JSON.stringify (objArray.sort ())),

或者寻找类似的

objArray.sort(function(a, b) {
    var classA = a.ClassName.toLowerCase(), classB = b.ClassName.toLowerCase();
    if(classA<classB){
        return -1;}
    if(classA>classB){
        return 1;}
    return 0;
});
objArray.sort(function(a, b) {
    var classA = a.ClassName.toLowerCase(), classB = b.ClassName.toLowerCase();
    if(classA===classB){
            var startA =new Date(a.StartDate), startB=new Date(b.StartDate);
            return startA-startB;
     }
    return 0;
});