通过布尔属性对对象的 Javascript 排序数组

查看最后的编辑实际问题。

好吧,我有这样一个场景:

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]

如果我这么做:

a.sort(function(a,b){return !a && b});

它给了我这个:

[false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]

这是一种排序... 但不完全是... : (

如何对这个数组排序?

编辑:

如果你想知道为什么我没有使用 a.sort ()是因为我的实际数组是对象,而不是像我发布的一个普通数组。真正的元素看起来像[{ xx: true } ,{ xx: false } ,... ]

171986 次浏览

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];
    

    

a.sort(function(x, y) {
// true values first
return (x === y)? 0 : x? -1 : 1;
// false values first
// return (x === y)? 0 : x? 1 : -1;
});
    

console.log(a);

如果 a 和 b 具有相同的值,则必须返回0; 如果 a 为 true,则返回 -1,否则返回1。

更简单的方法:

a = [{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false},{xx:true},{xx:false}];


a.sort(function(a,b){return a.xx-b.xx});


console.log(a);

如果希望以另一种方式排序,可以在 sort ()之后调用 a.return ()。

编辑: 编辑以反映对象数组而不是布尔值数组排序的更新问题。

PFB 的解决方案为我工作的打字机角度2以及,

  let a = [{aa:"1",xx:true},{aa:"10",xx:false},{aa:"2",xx:true},{aa:"11",xx:false},{aa:"3",xx:true},{aa:"12",xx:false},{aa:"4",xx:true},{aa:"13",xx:false},{aa:"5",xx:true},{aa:"14",xx:false},{aa:"6",xx:true},{aa:"15",xx:false},{aa:"7",xx:true},{aa:"16",xx:false},{aa:"8",xx:true},{aa:"17",xx:false},{aa:"9",xx:true},{aa:"18",xx:false}];


//a.sort(function(a,b){return a.xx-b.xx});
a.sort(function (x, y) {
// true values first
return (x.xx === y.xx) ? 0 : x ? -1 : 1;
// false values first
// return (x === y)? 0 : x? 1 : -1;
});
return JSON.stringify(a);

为了防止隐式类型转换(TypeScript 等语言不喜欢隐式类型转换) ,可以使用 Number()显式地将布尔值转换为数字:

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];
a.sort(function(x, y) {
return Number(x) - Number(y);
});
console.log(a);

或使用箭头函数:

a = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];
a.sort((x, y) => Number(x) - Number(y));
console.log(a);

比较函数的一个非常简单的解决方案是检查 a < b,当转换为数字时,它是给出0还是1。然后我们要映射0到 -1和1到1。要做到这一点,你只需要乘以2然后减去1。

data.sort(function (a, b) {
return (a < b) * 2 - 1
}

或者只是

data.sort((a, b) => (a < b) * 2 - 1)

问题解决了!

如果您的任何值是 null,它们将被视为假值(null*2 === 0) ,任何值是 undefined将成为 NaN(undefined*2 === NaN) ,这将使其在任一排序方向上持续存在。

简单的解决办法:

[true, false, true, false].sort((a, b) => b - a)

console.log([true, false, true, false].sort((a, b) => b - a));

数组没有任何相等的位置,所以为什么不去掉等于检查,总是返回 -1或1。这种方法在 TS 中运行良好。

a.sort(x => x ? -1 : 1)

注意: 我有点担心这会对 sort 函数的内部结构产生什么影响,但它似乎起到了作用。

如果要进行反向排序

a.sort(x => !x ? -1 : 1)

我在 return (x.xx === y.xx) ? 0 : x ? -1 : 1;上发现了打印错误

这是我的解决方案,当您想要排序的布尔属性

this.mediaList.sort( (a: MediaAutosubscriptionModel, b: MediaAutosubscriptionModel) => {
let status1: number = a.status === StatusEnum.ACTIVE ? 1 : 0;
let status2: number = b.status === StatusEnum.ACTIVE ? 1 : 0;
let comparison: number = 0;
let direction: number = this.sortDirection === SortDirectionsEnum.ASC ? -1 : 1;
if (status1 > status2) {
comparison = direction;
} else if (status1 < status2) {
comparison = -1 * direction;
}
return comparison;
});

我想看看我是否可以不使用 ? :操作符做到这一点,只是为了好玩。

注意

这适用于所有可排序的数据类型(字符串、数字) ,而不仅仅是原始布尔值。我不知道这是否比 ? :更快,它更复杂。我只是讨厌条件句,所以这只是个人偏好。

  var b = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
.sort((a,b) => Number(a > b) * 2 - 1);

我可以把它变成一个实用函数,并给它一个有意义的名字:

  var sortOrder = {
asc: (a,b) => Number(a > b) * 2 - 1,
desc: (a,b) => Number(a < b) * 2 - 1
}

然后我就可以:

  var b = [false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
.sort(sortOrder.asc);
a=[true,false,true,false,true];
 

a.sort(function(x, y) {
a1=x?1:0
b1=y?1:0
return a1-b1
});

我也遇到了这个问题,这里是我的部分,我希望它有所帮助:

orders.sort((x, y) => {
if (x === y) return 0;
if (x) return -1;
return 1;
});

一个布尔数组,有足够的条目来表示所有的转换,例如 true 到 true,true 到 false,false 到 false,false 到 true。

var boolarray = [true, false, true, true, false, false, true]
boolarray.sort( (a,b) => !(a ^ b) ? 0 : a ? -1 : 1)

排序反转输入的 xor。如果输入相同,那么返回0,如果不相同,如果‘ a’输入为真,那么‘ b’必须为假,所以返回 -1,反之亦然,返回1。

‘ a’和‘ b’布尔值在它们不同时进行排序,而在 一样。

要对对象使用此方法,只需对排序参数使用对象成员名称:

var objarray = [{xx:true}, {xx:false}, {xx:true}, {xx:true}, {xx:false}, {xx:false}, {xx:true}]
objarray.sort( (a,b) => !(a.xx ^ b.xx) ? 0 : a.xx ? -1 : 1)

不使用任何 ES6函数的时间和空间优化-

const data = [false, true, true, true, false, false, false, true];
let lastElementUnchecked;
for(let i=0; i<data.length; i++){
if(data[i] && lastElementUnchecked !== undefined){
let temp = data[i];
data[i] = data[lastElementUnchecked];
data[lastElementUnchecked] = temp;
i = lastElementUnchecked;
lastElementUnchecked = undefined;
}else{
if(!data[i] && lastElementUnchecked === undefined){
lastElementUnchecked = i;
}
}
}
console.log(data)