javascript Javascript按布尔属性对对象数组进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17387435/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 08:08:19  来源:igfitidea点击:

Javascript sort array of objects by a boolean property

javascriptsorting

提问by PCoelho

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. The real one has elements that look like [{xx:true},{xx:false},...]

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

回答by c.P.u1

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。

回答by dandavis

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.

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

回答by sroes

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

回答by Сергей Мисник

Simple solution:

简单的解决方案:

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

回答by Kristjan Liiva

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)

回答by dreamdeveloper

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

回答by MattCochrane

A pretty simple solution for the comparison function is to check if a < b, this gives 0 or 1 when converted to a number. We then want to map 0 to -1 and 1 to 1. To do that you can just multiply by 2 then subtract 1.

比较函数的一个非常简单的解决方案是检查 if a < b,这在转换为数字时给出 0 或 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 nullthey are treated as false (null*2 === 0) and any value that is undefinedwill become NaN(undefined*2 === NaN) which should make it last in either sort direction.

如果您的任何值是null它们,它们将被视为 false ( null*2 === 0) 并且任何值都undefined将变为NaN( undefined*2 === NaN) 这应该使其在任一排序方向持续。

回答by chriscrossweb

I got typescript errors on the 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;
    });

回答by toddmo

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