Javascript:按数字属性排序对象数组,包括未定义

时间:2019-05-26 11:10:49

标签: javascript

我可以定义一个数字数组并像这样对它们进行排序

var array = ['2', undefined, '1'];
array.sort((a, b) => a - b);
console.log(array);

输出为1, 2, null

我有一个可以包含number属性的对象数组,可以这样定义。并非所有对象都具有number属性。现在,我想通过number属性对对象数组进行排序。所以我尝试了这个:

var array = [
  { number: 2 },
  {},
  { number: 1 }
];
array.sort((a, b) => a.number - b.number);
console.log(array);

输出不是我想要的。我得到2, undefined, 1

如果数组中的所有对象都定义了number属性,则相同的排序函数将生成1, 2,这是我期望的结果。

var array = [
  { number: 2 },
  { number: 1 }
];
array.sort((a, b) => a.number - b.number);
console.log(array);

所以我的问题是,按属性对对象数组进行排序的最佳方法是什么,而该属性并不总是定义的。预期结果是对象按属性(数字)排序,而对象未在数组末尾定义该属性。

到目前为止,我唯一的解决方案是迭代集合,如果未定义属性,请将属性设置为0或null。然后,我可以将对象数组传递给sort函数,它可以根据需要工作。有没有比这更好的方法了?

Jfiddle:https://jsfiddle.net/t2r6z13e/1/

5 个答案:

答案 0 :(得分:2)

您可以返回要比较的每个对象上是否存在number属性之间的差异,或者返回它们的number属性之间的差异(在两个对象都具有上述属性的情况下):< / p>

var array = [
  { number: 2 },
  {},
  { number: 1 }
];

array.sort((a, b) => {
  const aHas = typeof a.number !== 'undefined';
  const bHas = typeof b.number !== 'undefined';
  return (bHas - aHas) || (aHas === true && a.number - b.number) || 0;
});
console.log(array);

答案 1 :(得分:2)

您可以为具有对象跨度的数组元素提供默认值:{default, ...item}

var array = [
  { number: 2 },
  {},
  { number: 1 },
  {},
  { number: 0 },
];

array.sort((a, b) => (
    {number: Number.MAX_VALUE, ...a}.number -
    {number: Number.MAX_VALUE, ...b}.number));

console.log(array);

如果目标尚不支持对象传播,则将其替换为Object.assign

答案 2 :(得分:1)

有点不可读:

var array = [ { number: 2 }, { }, { number: 1 } ];

array.sort((a, b) => 'number' in a ? 'number' in b ? a.number - b.number : -1 : 1);

console.log(array);

或者更具可读性:

var array = [ { number: 2 }, { }, { number: 1 } ];

array.sort((a, b) => !('number' in a) ? 1 : !('number' in b) ? -1 : a.number - b.number);

console.log(array);

答案 3 :(得分:1)

解释在注释中:

let array = [
  {},
  { number: 2 },
  {},
  { number: 1 }
];

array.sort((a, b) => {
  // two undefined values should be treated as equal ( 0 )
  if( typeof a.number === 'undefined' && typeof b.number === 'undefined' )
    return 0;
  // if a is undefined and b isn't a should have a lower index in the array
  else if( typeof a.number === 'undefined' )
    return 1;
    // if b is undefined and a isn't a should have a higher index in the array
  else if( typeof b.number === 'undefined' )
    return -1;
    // if both numbers are defined compare as normal
  else
    return a.number - b.number;
});

console.log( array );

答案 4 :(得分:0)

如果提供了compareFunction,则根据比较函数的返回值对所有未定义的数组元素进行排序(所有未定义的元素均排序到数组的末尾,而无需调用compareFunction)。

在您的代码中,如果数组具有数字排序功能,则不会调用未定义值的项目;而对于带有对象的数组,则定义了对象,但未定义obj.number,因此sort函数也调用了blank({})对象,并要求在sort函数中添加对 number 的未定义检查。