How to perform case-insensitive sorting array of string in JavaScript?

JavascriptSortingCase Insensitive

Javascript Problem Overview


I have an array of strings I need to sort in JavaScript, but in a case-insensitive way. How to perform this?

Javascript Solutions


Solution 1 - Javascript

In (almost :) a one-liner

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

Which results in

[ 'bar', 'Foo' ]

While

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

results in

[ 'Foo', 'bar' ]

Solution 2 - Javascript

It is time to revisit this old question.

You should not use solutions relying on toLowerCase. They are inefficient and simply don't work in some languages (Turkish for instance). Prefer this:

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

Check the documentation for browser compatibility and all there is to know about the sensitivity option.

Solution 3 - Javascript

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

EDIT: Please note that I originally wrote this to illustrate the technique rather than having performance in mind. Please also refer to answer @Ivan Krechetov for a more compact solution.

Solution 4 - Javascript

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

Solution 5 - Javascript

ES6 version:

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

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

Solution 6 - Javascript

You can also use the new Intl.Collator().compare, per MDN it's more efficient when sorting arrays. The downside is that it's not supported by older browsers. MDN states that it's not supported at all in Safari. Need to verify it, since it states that Intl.Collator is supported.

> When comparing large numbers of strings, such as in sorting large arrays, it is better to create an Intl.Collator object and use the function provided by its compare property

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

Solution 7 - Javascript

If you want to guarantee the same order regardless of the order of elements in the input array, here is a stable 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;
});

Solution 8 - Javascript

Normalize the case in the .sort() with .toLowerCase().

Solution 9 - Javascript

You can also use the Elvis operator:

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

Gives:

biscuit,Bob,charley,fudge,Fudge

The localeCompare method is probably fine though...

Note: The Elvis operator is a short form 'ternary operator' for if then else, usually with assignment.
If you look at the ?: sideways, it looks like Elvis...
i.e. instead of:

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

you can use:

x = y?1:2;

i.e. when y is true, then return 1 (for assignment to x), otherwise return 2 (for assignment to x).

Solution 10 - Javascript

The other answers assume that the array contains strings. My method is better, because it will work even if the array contains null, undefined, or other non-strings.

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

The null will be sorted between 'nulk' and 'nulm'. But the undefined will be always sorted last.

Solution 11 - Javascript

In support of the accepted answer I would like to add that the function below seems to change the values in the original array to be sorted so that not only will it sort lower case but upper case values will also be changed to lower case. This is a problem for me because even though I wish to see Mary next to mary, I do not wish that the case of the first value Mary be changed to lower case.

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

In my experiments, the following function from the accepted answer sorts correctly but does not change the values.

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

Solution 12 - Javascript

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

In above function, if we just compare when lower case two value a and b, we will not have the pretty result.

Example, if array is [A, a, B, b, c, C, D, d, e, E] and we use the above function, we have exactly that array. It's not changed anything.

To have the result is [A, a, B, b, C, c, D, d, E, e], we should compare again when two lower case value is equal:

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

Solution 13 - Javascript

This may help if you have struggled to understand:

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/

Solution 14 - Javascript

I wrapped the top answer in a polyfill so I can call .sortIgnoreCase() on string arrays

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

Solution 15 - Javascript

Wrap your strings in / /i. This is an easy way to use regex to ignore casing

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJ&#233;r&#244;me VerstryngeView Question on Stackoverflow
Solution 1 - JavascriptIvan KrechetovView Answer on Stackoverflow
Solution 2 - JavascriptZunTzuView Answer on Stackoverflow
Solution 3 - Javascriptron tornambeView Answer on Stackoverflow
Solution 4 - JavascriptNiet the Dark AbsolView Answer on Stackoverflow
Solution 5 - JavascriptNic ScozzaroView Answer on Stackoverflow
Solution 6 - JavascriptmateuscbView Answer on Stackoverflow
Solution 7 - JavascriptAalex GabiView Answer on Stackoverflow
Solution 8 - Javascriptuser1106925View Answer on Stackoverflow
Solution 9 - JavascriptAndySView Answer on Stackoverflow
Solution 10 - JavascriptJohn HenckelView Answer on Stackoverflow
Solution 11 - JavascriptJohn ShearingView Answer on Stackoverflow
Solution 12 - JavascriptEnvyView Answer on Stackoverflow
Solution 13 - JavascriptIan JamiesonView Answer on Stackoverflow
Solution 14 - JavascriptJason WatmoreView Answer on Stackoverflow
Solution 15 - Javascriptuser3225968View Answer on Stackoverflow