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

我有一个字符串数组,我需要在JavaScript中排序,但以不区分大小写的方式。如何做到这一点?

163403 次浏览

.toLowerCase()规范化.sort()中的case。

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

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

在(几乎:)一行代码中

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

结果是

[ 'bar', 'Foo' ]

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

结果

[ 'Foo', 'bar' ]

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

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

你也可以使用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);

给:

biscuit,Bob,charley,fudge,Fudge

localeCompare方法可能很好…

< p > 注意:Elvis操作符是if then else的“三元操作符”的缩写形式,通常带有赋值。 < br > 如果你看?:侧面,它看起来像猫王…
例如:

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

你可以使用:

x = y?1:2;

也就是说,当y为真时,则返回1(用于赋值给x),否则返回2(用于赋值给x)。

如果你在努力理解以下内容,这可能会有所帮助:

var array = ["sort", "Me", "alphabetically", "But", "Ignore", "case"];
console.log('Unordered array ---', array, '------------');


array.sort(function(a,b) {
a = a.toLowerCase();
b = b.toLowerCase();
console.log("Compare '" + a + "' and '" + b + "'");


if( a == b) {
console.log('Comparison result, 0 --- leave as is ');
return 0;
}
if( a > b) {
console.log('Comparison result, 1 --- move '+b+' to before '+a+' ');
return 1;
}
console.log('Comparison result, -1 --- move '+a+' to before '+b+' ');
return -1;




});


console.log('Ordered array ---', array, '------------');




// return logic


/***
If compareFunction(a, b) is less than 0, sort a to a lower index than b, i.e. a comes first.
If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
If compareFunction(a, b) is greater than 0, sort b to a lower index than a.
***/

http://jsfiddle.net/ianjamieson/wmxn2ram/1/

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

在上面的函数中,如果我们只比较小写的两个值a和b,我们将不会得到漂亮的结果。

例如,如果数组是[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;
}
}
}

/ /i中包装字符串。这是使用正则表达式忽略大小写的一种简单方法

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

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

null将在'nulk'和'nulm'之间排序。但是undefined将被总是排在最后。

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

当比较大量字符串时,例如对大型数组排序时,最好创建Intl。对象,并使用其compare属性提供的函数

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

我把上面的答案包装在一个填充中,这样我就可以在字符串数组上调用.sortIgnoreCase()

// Array.sortIgnoreCase() polyfill
if (!Array.prototype.sortIgnoreCase) {
Array.prototype.sortIgnoreCase = function () {
return this.sort(function (a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
};
}

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

你不应该使用依赖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;
}
);

在我的实验中,下面的函数从接受的答案正确排序,但没有改变值。

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