js数组对象中的数据排序问题?

array = [{ a: 0, b: '2023-01-12 12:13:23'}]

array数组数据格式如上所示,现在要求的排序规则是:优先展示a值为0的对象,再展示a值为1的对象,并且还要根据b值倒序排列。

请问这种要怎么实现呢?

阅读 2.8k
5 个回答

写一个 sort 就好了呀,只不过规则需要借助 if 去做一下判断。

var list = [
    { a: 0, b: '2023-01-12 12:13:23'},
    { a: 1, b: '2023-01-12 12:15:23'},
    { a: 1, b: '2023-01-12 12:13:23'},
    { a: 0, b: '2023-01-01 12:13:23'},
]
list.sort((prev,next)=>{
  // 如果属性 a 一致,则对比属性 b,倒叙
  if(prev.a === next.a) return new Date(next.b).valueOf() - new Date(prev.b).valueOf()
  // 属性 a 的不一致,对比属性 a, 正序
  return prev.a - next.a
})
// (4) [{…}, {…}, {…}, {…}]
// 0: {a: 0, b: '2023-01-12 12:13:23'}
// 1: {a: 0, b: '2023-01-01 12:13:23'}
// 2: {a: 1, b: '2023-01-12 12:15:23'}
// 3: {a: 1, b: '2023-01-12 12:13:23'}

相关阅读
Array.prototype.sort() - JavaScript | MDN
Array.prototype.sort() 的排序稳定性 | 数组的扩展 - ECMAScript 6入门

let array = [
    { a: 0, b: '2023-01-12 12:13:23'},
    { a: 0, b: '2023-01-12 12:16:23'},
    { a: 1, b: '2023-01-12 12:17:23'},
    { a: 0, b: '2023-01-12 12:12:23'},
    { a: 1, b: '2023-01-12 12:10:23'}
]
// 第一种
array.sort((s, v) => new Date(v.b).getTime() - new Date(s.b).getTime())
array.sort((s, v) => s.a - v.a)
console.log(array);

image.png

没有示例数据,所以随机产生一个

// 工具:随机整数
function randomInt(maxExclude) {
    return ~~(Math.random() * maxExclude);
}

// 随机对象
function createRandom() {
    return {
        a: randomInt(3),
        b: [
            [
                2020 + randomInt(3),
                `${1 + randomInt(12)}`.padStart(2, "0"),
                `${1 + randomInt(28)}`.padStart(2, "0"),
            ].join("-"),
            [24, 60, 60].map(n => `${randomInt(n)}`.padStart(2, 0)).join(":")
        ].join(" ")
    };
}

// 产生 10 个随机对象
const data = Array.from({ length: 10 }, () => createRandom());
console.log(data);

然后是排序

data.sort((a, b) => {
    // a 属性相同的情况下对比 b,直接按日期对比
    // 格式整齐的情况下可以按字符串对比(下面注释,用 IIFE 简化了属性取值)
    return (a.a === b.a)
        ? new Date(b.b) - new Date(a.b)
        // ? ((a, b) => b > a ? 1 : b < a ? -1 : 0)(a.b, b.b)
        : a.a - b.a;
});

console.log(data);
2023-01-18 补充

如果在排序中去生成 Date 对象,在数据量较大的时候,会大量重复这个操作,浪费算力。这种情况下可以先生成一个辅助对象来排序,提前处理好日期字符串(这种费空间)

const newData = data
    .map(it => ({
        a: it.a,        // 可以不做这个缓存用 x.it.a 来访问
        t: Date.parse(it.b),
        it
    }))
    .sort((a, b) => a.a === b.a
        ? b.t - a.t
        : a.a - b.a
    )
    .map(w => w.it);


console.log(newData);

临时对应的 a 属性缓存可以不做,比较的时候通过 a.it.ab.it.a 来访问。但是访问属性操作也存在计算,能省点是点(空间换时间)

新手上路,请多包涵
function mySort(arr) {
  const $arr = JSON.parse(JSON.stringify(arr));
  // 先按a排序
  $arr.sort((i, j) => i.a - j.a);

  // 记录a的值
  const aArr = [...new Set($arr.map((i) => i.a))];

  // 生成利于排序的数据结构
  const myData = aArr.map((item) => {
    return $arr.filter((el) => el.a === item);
  });

  myData.forEach((el) => {
    // 换成时间排序逻辑,moment().isBefore之类的
    el.sort((i, j) => j.b - i.b);
  });

  // 数组扁平化
  let result = myData.flat();

  return result;
}
list.sort((m,n) => m.a - n.a || new Date(n.b).getTime() - new Date(m.b).getTime())

m.an.a相等时,取后面这项

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏