我有一个字符串数组,需要在 JavaScript 中进行排序,但不区分大小写。如何执行此操作?
(几乎:)一句台词
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
这会导致
[ 'bar', 'Foo' ]
同时
["Foo", "bar"].sort();
结果
[ 'Foo', 'bar' ]
是时候重新审视这个老问题了。
您不应使用依赖于
toLowerCase
的解决方案。它们“效率低下”,并且在某些语言中“不起作用”(例如土耳其语)。更喜欢这个:
['Foo', 'bar'].sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))
检查文档以了解浏览器兼容性以及有关
sensitivity
myArray.sort(
function(a, b) {
if (a.toLowerCase() < b.toLowerCase()) return -1;
if (a.toLowerCase() > b.toLowerCase()) return 1;
return 0;
}
);
请注意,我最初写这篇文章是为了说明该技术,而不是考虑性能。另请参阅答案@Ivan Krechetov以获得更紧凑的解决方案。
ES6版本:
您还可以使用新的
,根据 MDN,它在对数组进行排序时更高效
。缺点是旧版浏览器不支持它。MDN 声明 Safari 根本不支持它。需要验证一下,因为它声明支持
Intl.Collator
["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]
如果您想保证相同的顺序,而不管输入数组中元素的顺序如何,这里有一个稳定
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;
});
用
.sort()
.toLowerCase()
中的情况标准化。
您还可以使用 Elvis 运算符:
给予:
biscuit,Bob,charley,fudge,Fudge
localeCompare 方法可能没问题......
注意:Elvis 运算符是 if then else 的缩写“三元运算符”,通常带有赋值。 如果你从侧面看,它看起来像猫王......
即代替:
if (y) {
x = 1;
} else {
x = 2;
}
您可以使用:
x = y?1:2;
即当 y 为真时,返回 1(分配给 x),否则返回 2(分配给 x)。
其他答案假设数组包含字符串。我的方法更好,因为即使数组包含 null、未定义或其他非字符串,它也能工作。
null
将在“nulk”和“nulm”之间排序。但
undefined
将
始终排在最后。
arr.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
if( a == b) return 0;
if( a > b) return 1;
return -1;
});
例如,如果数组是 [A, a, B, b, c, C, D, d, e, E] 并且我们使用上面的函数,我们就得到了这个数组。没有改变任何东西。
要得到的结果是[A, a, B, b, C, c, D, d, E, e],当两个小写值相等时,我们应该再次比较:
function caseInsensitiveComparator(valueA, valueB) {
var valueALowerCase = valueA.toLowerCase();
var valueBLowerCase = valueB.toLowerCase();
if (valueALowerCase < valueBLowerCase) {
return -1;
} else if (valueALowerCase > valueBLowerCase) {
return 1;
} else { //valueALowerCase === valueBLowerCase
if (valueA < valueB) {
return -1;
} else if (valueA > valueB) {
return 1;
} else {
return 0;
}
}
}
为了支持已接受的答案,我想补充一点,下面的函数似乎更改了要排序的原始数组中的值,以便它不仅会对小写字母进行排序,而且大写字母值也会更改为小写字母。这对我来说是一个问题,因为即使我希望看到 Mary 旁边的 Mary,我也不希望将第一个值 Mary 的大小写更改为小写。
在我的实验中,接受答案中的以下函数可以正确排序,但不会更改值。
["Foo", "bar"].sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
如果您很难理解,这可能会有所帮助:
将琴弦缠绕在
/ /i