如何在 JavaScript 中执行不区分大小写的字符串排序数组?

IT技术 javascript sorting case-insensitive
2021-02-01 19:11:55

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

6个回答

在(几乎:) 单行

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

这导致

[ 'bar', 'Foo' ]

尽管

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

结果是

[ 'Foo', 'bar' ]
请注意,并非所有平台/浏览器都支持 localeCompare 的高级选项。我知道在这个例子中没有使用它们,但只是想添加清楚。查看 MDN 了解更多信息
2021-03-13 19:11:55
@Milimetric 根据引用的页面,某些浏览器(例如 IE<11 或 Safari)不支持该功能。这里提到的解决方案非常好,但对于某些浏览器仍然需要向后移植/polyfill。
2021-03-20 19:11:55
+1表示在某些情况下默认情况下已经这样做toLowerCase()不调用localeCompare您可以在此处阅读有关要传递给它的参数的更多信息:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-22 19:11:55
如果你有一个大数组,使用它来items.sort(new Intl.Collator('en').compare)获得更好的性能是有意义的(见MDN。)
2021-03-22 19:11:55
如果您打算使用 localeCompare(),您可以使用不区分大小写的功能,例如:return a.localeCompare(b, 'en', {'sensitivity': 'base'});
2021-04-04 19:11:55

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

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

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

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

请注意,并非所有 javascript 引擎都支持此功能。
2021-03-12 19:11:55
似乎所有浏览器现在都支持 localCompare,除了某些移动浏览器不支持 2 个可选参数: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-13 19:11:55
看起来['Foo', 'bar'].sort((a,b) => a.localeCompare(b))也有效
2021-03-29 19:11:55
@Ollie Williams 没有语言环境和选项参数,使用的语言环境和排序顺序完全取决于实现
2021-04-05 19:11:55
myArray.sort(
  function(a, b) {
    if (a.toLowerCase() < b.toLowerCase()) return -1;
    if (a.toLowerCase() > b.toLowerCase()) return 1;
    return 0;
  }
);

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

@Jacob 公平地说,接受的答案具有相同的基本问题:它可能.toLowerCase()为数组中的每个项目调用多次。例如,当以相反顺序对 10 个项目进行排序时,对比较函数进行了 45 次调用。var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
2021-03-19 19:11:55
这可以toLowerCase在每个字符串上调用两次;将字符串的降低版本存储在变量中会更有效。
2021-04-04 19:11:55
真的,谢谢。我写这篇文章时考虑的是清晰,而不是性能。我想我应该注意这一点。
2021-04-06 19:11:55
arr.sort(function(a,b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    if (a == b) return 0;
    if (a > b) return 1;
    return -1;
});
@AustinDavis"33" > "111" === true33 > 111 === false. 它按预期工作。
2021-03-12 19:11:55
对于表示数字的字符串,这可能无法按预期工作算术运算符将使用数字的语义而不是字符串。例如,如果我们有["111", "33"],我们可能希望它返回,["111", "33"]因为在字符代码排序中 1 在 3 之前。但是,此答案中的函数将返回,["33", "111"]因为 number33小于 number 111
2021-03-28 19:11:55
或者 return a === b ? 0 : a > b ? 1 : -1;
2021-03-29 19:11:55

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

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

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