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

时间:2012-01-25 01:52:14

标签: javascript sorting case-insensitive

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

14 个答案:

答案 0 :(得分:339)

在(差不多:)一个单线

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

结果是

[ 'bar', 'Foo' ]

虽然

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

结果

[ 'Foo', 'bar' ]

答案 1 :(得分:58)

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

修改 请注意,我最初写这篇文章是为了说明技术,而不是考虑到性能。请参阅@Ivan Krechetov的答案以获得更紧凑的解决方案。

答案 2 :(得分:24)

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

答案 3 :(得分:10)

如果您想保证输入数组中元素顺序的相同顺序,这里有一个stable排序:

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

答案 4 :(得分:8)

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

  

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

 body {
 padding-bottom: 55px;
 }

答案 5 :(得分:4)

使用.sort().toLowerCase()中的案例规范化。

答案 6 :(得分:4)

ES6版本:

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

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare

答案 7 :(得分:3)

您也可以使用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方法虽然可能很好......

注意:Elvis运算符是一个简短形式的“三元运算符”,用于if if else,通常是赋值。
如果你看看?:侧身,它看起来像猫王......
即代替:

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

你可以使用:

x = y?1:2;

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

答案 8 :(得分:3)

其他答案假设数组包含字符串。我的方法更好,因为即使数组包含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 总是始终排序。

答案 9 :(得分:0)

如果您难以理解,这可能会有所帮助:

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/

答案 10 :(得分:0)

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

答案 11 :(得分:0)

我在polyfill中包含了最顶层的答案,因此我可以在字符串数组上调用.sortIgnoreCase()

{{1}}

答案 12 :(得分:0)

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

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

答案 13 :(得分:-2)

将您的字符串换行/ /i。这是使用正则表达式忽略大小写

的简单方法