如何在 JavaScript 中执行不区分大小写的排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8996963/
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-08-24 08:20:25  来源:igfitidea点击:

How to perform case-insensitive sorting in JavaScript?

javascriptsortingcase-insensitive

提问by Jér?me Verstrynge

I have an array of strings I need to sort in JavaScript, but in a case-insensitive way. How to perform this?

我有一个需要在 JavaScript 中排序的字符串数组,但不区分大小写。如何执行此操作?

回答by Ivan Krechetov

In (almost :) a one-liner

在(几乎:) 单线

["Foo", "bar"].sort(function (a, b) {
    return a.toLowerCase().localeCompare(b.toLowerCase());
});

Which results in

这导致

[ 'bar', 'Foo' ]

While

尽管

["Foo", "bar"].sort();

results in

结果是

[ 'Foo', 'bar' ]

回答by ron tornambe

myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

EDIT:Please note that I originally wrote this to illustrate the technique rather than having performance in mind. Please also refer to answer @Ivan Krechetov for a more compact solution.

编辑:请注意,我最初写这个是为了说明技术而不是考虑性能。另请参阅回答@Ivan Krechetov 以获得更紧凑的解决方案。

回答by ZunTzu

It is time to revisit this old question.

是时候重新审视这个老问题了。

You should not use solutions relying on toLowerCase. They are inefficientand simply don't workin some languages (Turkish for instance). Prefer this:

您不应该使用依赖于toLowerCase. 它们效率低下,并且在某些语言(例如土耳其语)中根本不起作用。更喜欢这个:

['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))

Check the documentationfor browser compatibility and all there is to know about the sensitivityoption.

检查浏览器兼容性的文档以及有关该sensitivity选项的所有信息。

回答by Niet the Dark Absol

arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if (a == b) return 0;
    if (a > b) return 1;
    return -1;
});

回答by Aalex Gabi

If you want to guarantee the same order regardless of the order of elements in the input array, here is a stablesorting:

如果你想保证相同的顺序而不管输入数组中元素的顺序,这里是一个稳定的排序:

myArray.sort(function(a, b) {
    /* Storing case insensitive comparison */
    var comparison = a.toLowerCase().localeCompare(b.toLowerCase());
    /* If strings are equal in case insensitive comparison */
    if (comparison === 0) {
        /* Return case sensitive comparison instead */
        return a.localeCompare(b);
    }
    /* Otherwise return result */
    return comparison;
});

回答by mateuscb

You can also use the new Intl.Collator().compare, per MDN it's more efficientwhen sorting arrays. The downside is that it's not supported by older browsers. MDN states that it's not supported at all in Safari. Need to verify it, since it states that Intl.Collatoris supported.

您还可以使用新的Intl.Collator().compare,每个 MDN在排序数组时效率更高。缺点是旧浏览器不支持它。MDN 声明它在 Safari 中完全不受支持。需要验证它,因为它声明Intl.Collator支持。

When comparing large numbers of strings, such as in sorting large arrays, it is better to create an Intl.Collator object and use the function provided by its compare property

比较大量字符串时,例如对大型数组进行排序时,最好创建一个 Intl.Collat​​or 对象并使用其 compare 属性提供的函数

["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]

回答by mateuscb

Normalize the case in the .sort()with .toLowerCase().

规范化.sort()with 中的案例.toLowerCase()

回答by AndyS

You can also use the Elvis operator:

您还可以使用 Elvis 运算符:

arr = ['Bob', 'charley', 'fudge', 'Fudge', 'biscuit'];
arr.sort(function(s1, s2){
    var l=s1.toLowerCase(), m=s2.toLowerCase();
    return l===m?0:l>m?1:-1;
});
console.log(arr);

Gives:

给出:

biscuit,Bob,charley,fudge,Fudge

The localeCompare method is probably fine though...

虽然 localeCompare 方法可能很好......

Note: The Elvis operator is a short form 'ternary operator' for if then else, usually with assignment.
If you look at the ?: sideways, it looks like Elvis...
i.e. instead of:

注意:Elvis 运算符是 if then else 的缩写“三元运算符”,通常带有赋值。
如果你看 ?: 侧面,它看起来像猫王......
即而不是:

if (y) {
  x = 1;
} else {
  x = 2;
}

you can use:

您可以使用:

x = y?1:2;

i.e. when y is true, then return 1 (for assignment to x), otherwise return 2 (for assignment to x).

即当 y 为真时,则返回 1(赋值给 x),否则返回 2(赋值给 x)。

回答by John Henckel

The other answers assume that the array contains strings. My method is better, because it will work even if the array contains null, undefined, or other non-strings.

其他答案假设数组包含字符串。我的方法更好,因为即使数组包含空值、未定义或其他非字符串,它也能工作。

var notdefined;
var myarray = ['a', 'c', null, notdefined, 'nulk', 'BYE', 'nulm'];

myarray.sort(ignoreCase);

alert(JSON.stringify(myarray));    // show the result

function ignoreCase(a,b) {
    return (''+a).toUpperCase() < (''+b).toUpperCase() ? -1 : 1;
}

The nullwill be sorted between 'nulk' and 'nulm'. But the undefinedwill be alwayssorted last.

null将“nulk”和“nulm”之间进行排序。但undefined始终排序最后。

回答by John Shearing

In support of the accepted answer I would like to add that the function below seems to change the values in the original array to be sorted so that not only will it sort lower case but upper case values will also be changed to lower case. This is a problem for me because even though I wish to see Mary next to mary, I do not wish that the case of the first value Mary be changed to lower case.

为了支持接受的答案,我想补充一点,下面的函数似乎更改了要排序的原始数组中的值,这样它不仅会排序小写,而且大写值也将更改为小写。这对我来说是一个问题,因为即使我希望看到 Mary 旁边的 Mary,我也不希望第一个值 Mary 的大小写更改为小写。

myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

In my experiments, the following function from the accepted answer sorts correctly but does not change the values.

在我的实验中,接受的答案中的以下函数可以正确排序,但不会更改值。

["Foo", "bar"].sort(function (a, b) {
    return a.toLowerCase().localeCompare(b.toLowerCase());
});