如何在Javascript中执行不区分大小写的sorting?
我有一个string数组,我需要在JavaScript中sorting,但以不区分大小写的方式。 如何执行此操作?
在(几乎:)一个class轮
["Foo", "bar"].sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); });
哪个结果
[ 'bar', 'Foo' ]
而
["Foo", "bar"].sort();
结果是
[ 'Foo', 'bar' ]
myArray.sort( function(a, b) { if (a.toLowerCase() < b.toLowerCase()) return -1; if (a.toLowerCase() > b.toLowerCase()) return 1; return 0; } );
编辑:请注意,我最初写这个来说明技术,而不是记住性能。 请参阅@Ivan Krechetov的答案,以获得更紧凑的解决scheme。
arr.sort(function(a,b) { a = a.toLowerCase(); b = b.toLowerCase(); if( a == b) return 0; if( a > b) return 1; return -1; });
如果你想保证相同的顺序,不pipeinput数组中元素的顺序如何,这里是一个稳定的sorting:
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; });
使用.toLowerCase()
标准化.sort()
中的.toLowerCase()
。
您也可以使用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方法可能是好的,但…
注:猫王操作符是一个简短的“三元操作符”,如果是其他的,通常是赋值。
如果你看着侧面,看起来像猫王
即而不是:
if (y) { x = 1; } else { x = 2; }
您可以使用:
x = y?1:2;
即当y为真时,则返回1(用于赋值给x),否则返回2(用于赋值给x)。
您也可以使用新的Intl.Collator().compare
,每个MDN在sorting数组时更高效 。 缺点是,由于旧版浏览器不支持。 MDN声明,它在Safari中完全不受支持。 需要validation它,因为它声明Intl.Collator
是受支持的。
比较大量string时,比如在sorting大数组时,最好创build一个Intl.Collator对象,并使用compare属性提供的函数
["Foo", "bar"].sort(Intl.Collator().compare); //["bar", "Foo"]
其他答案假定数组包含string。 我的方法更好,因为即使数组包含null,undefined或其他非string,它也可以工作。
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
将被sorting在'nulk'和'nulm'之间。 但undefined
将始终sorting最后。
这可能有助于你如果努力去理解:
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, ie 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 (eg 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. ***/
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; } } }
把你的string包装在/ /i
。 这是一个使用正则expression式忽略大小写的简单方法
我用polyfill封装了最上面的答案,所以我可以在string数组上调用.sortIgnoreCase()
// Array.sortIgnoreCase() polyfill if (!Array.prototype.sortIgnoreCase) { Array.prototype.sortIgnoreCase = function () { return this.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }); }; }