javascript-如何按3种不同的属性类型对对象数组进行排序? (字符串,整数,布尔值)

时间:2018-08-31 10:36:54

标签: javascript arrays sorting object

我有对象数组:

var a = [
  {"name": "BBB", "no": 2, "size1": [3], "size2": null },
  {"name": "AAA", "no": 5, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": [2], "size2": null },
  {"name": "AAA", "no": 4, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": null, "size2": [1] },
  {"name": "AAA", "no": 5, "size1": [2], "size2": null },
  {"name": "BBB", "no": 2, "size1": null, "size2": [1] },
];

我要这样排序,按name升序排序,然后按no升序排序,如果不为null,则按size1排序。

首先,我可以按nameno对其进行排序,但是此后我不知道如何按size1size2进行排序。如果不为null,则应首先按size1排序。 这是我要排序的代码

function sortObject(arrayObjects){
    arrayObjects.sort(function(a,b){
        if(a.name=== b.name){
            return (a.no - b.no);
        } else if(a.name > b.name){
            return 1;
        } else if(a.name < b.name){
            return -1;
        }
    });
}

预期结果

var a = [
  {"name": "AAA", "no": 4, "size1": null, "size2": [1] },
  {"name": "AAA", "no": 5, "size1": [2], "size2": null },
  {"name": "AAA", "no": 5, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": [2], "size2": null },
  {"name": "BBB", "no": 1, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 2, "size1": [3], "size2": null },
  {"name": "BBB", "no": 2, "size1": null, "size2": [1] },
]

4 个答案:

答案 0 :(得分:4)

您必须在第一个no中比较if

function sortObject(arrayObjects){
    arrayObjects.sort(function(a,b){
        if (a.name=== b.name) {
            if (a.no === b.no) {
                // Determines which size to use for comparison
                const aSize = a.size1 || a.size2;
                const bSize = b.size1 || b.size2;

                return (aSize[0] - bSize[0]);
            }
            return (a.no - b.no);
        } else if (a.name > b.name) {
            return 1;
        } else if (a.name < b.name) {
            return -1;
        }
    });
}

答案 1 :(得分:1)

您可以从30秒的代码(我维护的项目/网站)中使用orderBy的修改版本,该代码还会检查null并相应地定购:

var a = [
{"name": "BBB", "no": 2, "size1": [3], "size2": null },
{"name": "AAA", "no": 5, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": [2], "size2": null },
{"name": "AAA", "no": 4, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": null, "size2": [1] },
{"name": "AAA", "no": 5, "size1": [2], "size2": null },
{"name": "BBB", "no": 2, "size1": null, "size2": [1] },
];

const orderBy = (arr, props, orders) =>
  [...arr].sort((a, b) =>
    props.reduce((acc, prop, i) => {
      if (acc === 0) {
        const [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]];
        acc = p1 === null ? 1 : p2 === null ? -1 : p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
      }
      return acc;
    }, 0)
  );
  
 var aSorted = orderBy(a, ['name', 'no', 'size1', 'size2'], ['asc', 'asc', 'asc', 'asc']);
 
 console.log(aSorted);

orderBy的工作原理:

使用Array.sort()数组上的Array.reduce()props,默认值为0,根据传递的顺序使用数组解构来交换属性位置。如果没有传递orders数组,则默认情况下按'asc'排序。

答案 2 :(得分:1)

您可以这样做

  1. 用于字符串比较String.prototype.localeCompare()
  2. 用于数字/数组长度减法

演示

const arr = [
{"name": "BBB", "no": 2, "size1": [3], "size2": null },
{"name": "AAA", "no": 5, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": [2], "size2": null },
{"name": "AAA", "no": 4, "size1": null, "size2": [1] },
{"name": "BBB", "no": 1, "size1": null, "size2": [1] },
{"name": "AAA", "no": 5, "size1": [2], "size2": null },
{"name": "BBB", "no": 2, "size1": null, "size2": [1] },
];

arr.sort((a, b) => {
  let check = a.name.localeCompare(b.name);
  if (check == 0) {
    check = a.no - b.no;
    if (check == 0) {
      check = (b.size1 || []).length - (a.size1 || []).length;
    }
  }
  return check;
});

console.log(arr)
.as-console-wrapper {max-height: 100% !important;top: 0;}

答案 3 :(得分:1)

您可以尝试以下操作:

var a = [
  {"name": "AAA", "no": 4, "size1": null, "size2": [1] },
  {"name": "AAA", "no": 5, "size1": [2], "size2": null },
  {"name": "AAA", "no": 5, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 1, "size1": [2], "size2": null },
  {"name": "BBB", "no": 1, "size1": null, "size2": [1] },
  {"name": "BBB", "no": 2, "size1": [3], "size2": null },
  {"name": "BBB", "no": 2, "size1": null, "size2": [1] },
]

a.sort(function(a, b){
  return  a.name.localeCompare(b.name) ||
          a.no - b.no ||
          (b.size1 === null) - (a.size1 === null) ||
          (b.size2 === null) - (a.size2 === null)
});

console.log(a)