简体   繁体   English

Javascript 按 boolean 属性对对象数组进行排序

[英]Javascript sort array of objects by a boolean property

See edit at end for actual problem.有关实际问题,请参阅最后的编辑。

Ok, I have this scenario:好的,我有这种情况:

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]

Then if I do this:然后,如果我这样做:

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

It gives me this:它给了我这个:

[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]

It's sorta doing a sort... but not quite... :(它有点像在做某种……但不完全是……:(

How do I sort this array?如何对这个数组进行排序?

EDIT:编辑:

If you are wondering why I did not use just a.sort() is because my actual array is of objects, not a plain array like the one I posted.如果您想知道为什么我不只使用 a.sort() 是因为我的实际数组是对象,而不是像我发布的那样的普通数组。 The real one has elements that look like [{xx:true},{xx:false},...]真正的元素看起来像 [{xx:true},{xx:false},...]

 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);

You must return 0 when a and b both have the same value, -1 if a is true and 1 otherwise.当 a 和 b 具有相同的值时,您必须返回 0,如果 a 为真,则为 -1,否则为 1。

a simpler way:更简单的方法:

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);

you can call a.reverse() after the sort() if you want it sorted the other way..如果您希望它以另一种方式排序,您可以在 sort() 之后调用 a.reverse()。

EDIT: edited to reflect updated question of sorting an array of objects instead of an array of booleans.编辑:编辑以反映对对象数组而不是布尔数组进行排序的更新问题。

To prevent implicit type conversion (which languages like TypeScript don't like), you can use Number() to explicitly convert the boolean to a number:为了防止隐式类型转换(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);

Or using arrow functions:或者使用箭头函数:

 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);

简单的解决方案:

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

An array does not have any equal positions, so why not leave away the equals check, and always return either -1 or 1. This approach works well with TS.数组没有任何相等的位置,所以为什么不放弃相等检查,并始终返回 -1 或 1。这种方法适用于 TS。

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

Note: I am a bit concerned how this affects internals of the sort function, but it seems to do the trick.注意:我有点担心这会如何影响 sort 函数的内部结构,但它似乎可以解决问题。

If you want to reverse sort如果你想反向排序

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

PFB the solution worked for me in Typescript Angular 2 as well, PFB 该解决方案在 Typescript Angular 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);

A pretty simple solution for the comparison function is to check if a < b , this gives 0 or 1 when converted to a number.比较函数的一个非常简单的解决方案是检查a < b ,当转换为数字时,这会给出 0 或 1。 We then want to map 0 to -1 and 1 to 1. To do that you can just multiply by 2 then subtract 1.然后我们想将 0 映射到 -1,将 1 映射到 1。为此,您只需乘以 2 再减去 1。

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

or just要不就

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

Problem sorted!问题已解决!

If any of your values are null they are treated as false ( null*2 === 0 ) and any value that is undefined will become NaN ( undefined*2 === NaN ) which should make it last in either sort direction.如果您的任何值为null它们将被视为 false ( null*2 === 0 ) 并且任何undefined值都将变为NaN ( undefined*2 === NaN ),这应该使其在任一排序方向上都持续。

I wanted to see if I could do it without using the ? :我想看看我是否可以不使用? : ? : operator, just for fun. ? :运营商,只是为了好玩。

Note笔记

This works on all sortable data types (strings, numbers), not just raw booleans.这适用于所有可排序的数据类型(字符串、数字),而不仅仅是原始布尔值。 I'm not sure if this is faster than ? :我不确定这是否比? : ? : and it's more convoluted. ? :比较复杂。 I just get sick of conditionals so it's just personal preference.我只是厌倦了条件,所以这只是个人喜好。

  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);

I can turn that into a utility function and give it a meaningful name:我可以把它变成一个实用函数并给它一个有意义的名字:

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

so then I can:那么我可以:

  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);

I got typescript errors on the return (x.xx === y.xx) ? 0 : x ? -1 : 1;我在return (x.xx === y.xx) ? 0 : x ? -1 : 1;遇到打字稿错误return (x.xx === y.xx) ? 0 : x ? -1 : 1; return (x.xx === y.xx) ? 0 : x ? -1 : 1;

This is my solution when you want to sort on a boolean property当您想对布尔属性进行排序时,这是我的解决方案

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;
    });
a=[true,false,true,false,true];
 
a.sort(function(x, y) {
      a1=x?1:0
      b1=y?1:0
return a1-b1
    });

I also ran into this issue, here is my part, I hope it helps:我也遇到了这个问题,这是我的部分,我希望它有帮助:

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

A boolean array with enough entries to represent all transitions ie true to true, true to false, false to false, false to true.一个布尔数组,具有足够的条目来表示所有转换,即真到真、真到假、假到假、假到真。

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

The sort inverts the xor of the inputs.排序反转输入的异或。 If the inputs are the same then return 0, if they are not then, if the 'a' input is true 'b' must be false so return -1, and vice versa return 1.如果输入相同则返回 0,否则返回 0,如果不是,则如果“a”输入为真,“b”必须为假,因此返回 -1,反之亦然返回 1。

'a' and 'b' booleans are sorted when they differ and are ignored when the same. 'a' 和 'b' 布尔值在它们不同时排序,在相同时被忽略。

To use this method with objects just use the object member names for the sort arguments:要将此方法用于对象,只需将对象成员名称用于排序参数:

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)

Without using any ES6 function with time and space optimization -不使用任何 ES6 function 进行时间和空间优化 -

 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM