如何将带有条件的3个字段对对象数组排序,并且空值总是排在最后

时间:2019-07-06 06:56:47

标签: javascript arrays sorting

我有一个objectds数组,需要按3个日期字段(date1,date2,date3)排序

  1. 拳头按date1升序
  2. 如果还有更多具有相同date1的文档(按date3升序排序)
  3. (日期为null或未定义日期的文档必须在最后)
  4. 如果未定义date1或null(按date2升序排序),
  5. 如果还有更多具有相同date2的文档,则按date3升序排序

让我说我有这个数组:


    [
        { date1: null, date2: '20120-01-08', date3: '20120-01-06' },
        { date1: null, date2: '20120-01-09', date3: '20120-01-05' },
        { date1: null, date2: '20120-01-08', date3: '20120-01-05' },
        { date1: '20120-01-05', date2: '20120-01-07', date3: '20120-01-01' },
        { date1: '20120-01-04', date2: '20120-01-07', date3: '20120-01-02' },
        { date1: '20120-01-04', date2: '20120-01-10', date3: '20120-01-01' }
    ]

我需要得到这个:


    [
        { date1: '20120-01-04', date2: '20120-01-10', date3: '20120-01-01' },
        { date1: '20120-01-04', date2: '20120-01-07', date3: '20120-01-02' },
        { date1: '20120-01-05', date2: '20120-01-07', date3: '20120-01-01' },
        { date1: null, date2: '20120-01-08', date3: '20120-01-05' },
        { date1: null, date2: '20120-01-08', date3: '20120-01-06' },
        { date1: null, date2: '20120-01-09', date3: '20120-01-05' }
    ]

我尝试使用array.sort()并设法解决了最合适的3个要求:

  1. 拳头按date1升序
  2. 如果还有更多具有相同date1的文档(按date3升序排序)
  3. (日期为null或未定义日期的文档必须在最后)

使用此排序功能:


    var array = [
      { date2: "20120-01-08", date3: "20120-01-06" },
      { date2: "20120-01-09", date3: "20120-01-05" },
      { date2: "20120-01-08", date3: "20120-01-05" },
      { date1: "20120-01-05", date2: "20120-01-07", date3: "20120-01-01" },
      { date1: "20120-01-04", date2: "20120-01-07", date3: "20120-01-02" },
      { date1: "20120-01-04", date2: "20120-01-10", date3: "20120-01-01" }
    ];

    var result = array.sort(function(obj1, obj2) {
      if (!obj1.date1 || !obj2.date1) {
        return -1;
      } else {
        if (obj1.date1 > obj2.date1) return 1;
        if (obj1.date1 < obj2.date1) return -1;
        if (obj1.data3 > obj2.data3) return 1;
        if (obj1.date3 < obj2.date3) return -1;
        return 0;
      }
    });

我明白了:


    0: {date1: "20120-01-04", date2: "20120-01-10", date3: "20120-01-01"}
    1: {date1: "20120-01-04", date2: "20120-01-07", date3: "20120-01-02"}
    2: {date1: "20120-01-05", date2: "20120-01-07", date3: "20120-01-01"}
    3: {date2: "20120-01-08", date3: "20120-01-05"}
    4: {date2: "20120-01-09", date3: "20120-01-05"}
    5: {date2: "20120-01-08", date3: "20120-01-06"}

我不确定该如何解决2:

  1. 如果未定义date1或null(按date2升序排序),
  2. 如果还有更多具有相同date2的文档,则按date3升序排序

日期为undefined的记录未排序...

https://codepen.io/wyzix33/pen/agaKRp

谢谢

2 个答案:

答案 0 :(得分:2)

您可以排序

  • undefined的{​​{1}} / null / falsy值并将它们排序到底部,
  • date1date1虚假,
  • date2

date3
var data = [{ date1: null, date2: '20120-01-08', date3: '20120-01-06' }, { date1: null, date2: '20120-01-09', date3: '20120-01-05' }, { date1: null, date2: '20120-01-08', date3: '20120-01-05' }, { date1: '20120-01-05', date2: '20120-01-07', date3: '20120-01-01' }, { date1: '20120-01-04', date2: '20120-01-07', date3: '20120-01-02' }, { date1: '20120-01-04', date2: '20120-01-10', date3: '20120-01-01' }];

data.sort((a, b) =>
    !a.date1 - !b.date1 ||
    (a.date1 || a.date2).localeCompare(b.date1 || b.date2) ||
    a.date3.localeCompare(b.date3)
);

console.log(data);

答案 1 :(得分:0)

我使用了一些技巧,但是不幸的是花了很长时间才能执行! 要将未定义的null设置为最大日期,然后计算每个项目的值并进行比较!

var array = [{
    date1: null,
    date2: "20120-01-08",
    date3: "20120-01-06"
}, {
    date1: null,
    date2: "20120-01-08",
    date3: "20120-01-05"
}, {
    date1: null,
    date2: "20120-01-09",
    date3: "20120-01-05"
},
{
    date1: "20120-01-05",
    date2: "20120-01-07",
    date3: "20120-01-01"
}, {
    date1: "20120-01-04",
    date2: "20120-01-05",
    date3: "20120-01-02"
},
{
    date1: "20120-01-04",
    date2: "20120-01-07",
    date3: "20120-01-01"
}];

var result = array.sort(function(obj1, obj2) {

    var copyObj1 = {...obj1},copyObj2 ={...obj2};
    var largestDate = '20121-12-31'

    copyObj1.date1 = copyObj1.date1 || largestDate
    copyObj2.date1 = copyObj2.date1 || largestDate

    var value1 = Object.values(copyObj1).join('')
    var value2 = Object.values(copyObj2).join('')
    return value1.localeCompare(value2)
})