How to perform case-insensitive sorting in JavaScript?












163














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










share|improve this question





























    163














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










    share|improve this question



























      163












      163








      163


      29





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










      share|improve this question















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







      javascript sorting case-insensitive






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 12 '18 at 20:23









      Xufox

      10k62848




      10k62848










      asked Jan 25 '12 at 1:52









      Jérôme Verstrynge

      28k64219387




      28k64219387
























          13 Answers
          13






          active

          oldest

          votes


















          314














          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' ]





          share|improve this answer

















          • 8




            Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
            – Ayame__
            Jan 9 '14 at 15:05






          • 70




            If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
            – Michael Dyck
            Jul 30 '14 at 21:47








          • 1




            +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
            – Milimetric
            Sep 12 '14 at 15:26








          • 3




            @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
            – 3k-
            Apr 6 '15 at 14:18






          • 1




            If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
            – valtlai
            Apr 3 '18 at 10:00





















          57














          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.






          share|improve this answer



















          • 3




            This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
            – Jacob
            Aug 6 '13 at 17:23










          • True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
            – ron tornambe
            Aug 6 '13 at 19:00






          • 1




            @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
            – nothingisnecessary
            Dec 20 '16 at 21:44



















          24














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





          share|improve this answer























          • or return a === b ? 0 : a > b ? 1 : -1;
            – Devin G Rhode
            Dec 4 '17 at 22:46



















          18














          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.






          share|improve this answer





























            10














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





            share|improve this answer





























              7














              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"]





              share|improve this answer



















              • 3




                Screw old browsers; I'm using this.
                – Lonnie Best
                Feb 4 '18 at 14:27












              • This guy gets it
                – emptywalls
                Aug 6 '18 at 20:46



















              4














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






              share|improve this answer





























                3














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






                share|improve this answer



















                • 1




                  To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                  – Charles Wood
                  May 3 '18 at 15:27





















                2














                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.






                share|improve this answer





















                • (''+notdefined) === "undefined" so it'd sort before "z"
                  – MattW
                  Sep 14 '16 at 14:34












                • @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                  – John Henckel
                  Sep 15 '16 at 16:10










                • Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                  – MattW
                  Sep 15 '16 at 18:05










                • And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                  – MattW
                  Sep 15 '16 at 18:26






                • 1




                  Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                  – John Henckel
                  Sep 15 '16 at 21:09



















                0














                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/






                share|improve this answer





























                  0














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





                  share|improve this answer





























                    0














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





                    share|improve this answer





























                      -2














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






                      share|improve this answer























                      • The question is about sorting, not matching.
                        – Xufox
                        Sep 12 '18 at 20:24










                      protected by Pankaj Parkar Oct 19 '15 at 6:24



                      Thank you for your interest in this question.
                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                      Would you like to answer one of these unanswered questions instead?














                      13 Answers
                      13






                      active

                      oldest

                      votes








                      13 Answers
                      13






                      active

                      oldest

                      votes









                      active

                      oldest

                      votes






                      active

                      oldest

                      votes









                      314














                      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' ]





                      share|improve this answer

















                      • 8




                        Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
                        – Ayame__
                        Jan 9 '14 at 15:05






                      • 70




                        If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
                        – Michael Dyck
                        Jul 30 '14 at 21:47








                      • 1




                        +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                        – Milimetric
                        Sep 12 '14 at 15:26








                      • 3




                        @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
                        – 3k-
                        Apr 6 '15 at 14:18






                      • 1




                        If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
                        – valtlai
                        Apr 3 '18 at 10:00


















                      314














                      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' ]





                      share|improve this answer

















                      • 8




                        Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
                        – Ayame__
                        Jan 9 '14 at 15:05






                      • 70




                        If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
                        – Michael Dyck
                        Jul 30 '14 at 21:47








                      • 1




                        +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                        – Milimetric
                        Sep 12 '14 at 15:26








                      • 3




                        @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
                        – 3k-
                        Apr 6 '15 at 14:18






                      • 1




                        If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
                        – valtlai
                        Apr 3 '18 at 10:00
















                      314












                      314








                      314






                      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' ]





                      share|improve this answer












                      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' ]






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Mar 10 '12 at 9:43









                      Ivan Krechetov

                      13.2k84257




                      13.2k84257








                      • 8




                        Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
                        – Ayame__
                        Jan 9 '14 at 15:05






                      • 70




                        If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
                        – Michael Dyck
                        Jul 30 '14 at 21:47








                      • 1




                        +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                        – Milimetric
                        Sep 12 '14 at 15:26








                      • 3




                        @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
                        – 3k-
                        Apr 6 '15 at 14:18






                      • 1




                        If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
                        – valtlai
                        Apr 3 '18 at 10:00
















                      • 8




                        Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
                        – Ayame__
                        Jan 9 '14 at 15:05






                      • 70




                        If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
                        – Michael Dyck
                        Jul 30 '14 at 21:47








                      • 1




                        +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                        – Milimetric
                        Sep 12 '14 at 15:26








                      • 3




                        @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
                        – 3k-
                        Apr 6 '15 at 14:18






                      • 1




                        If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
                        – valtlai
                        Apr 3 '18 at 10:00










                      8




                      8




                      Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
                      – Ayame__
                      Jan 9 '14 at 15:05




                      Do mind that localeCompare's advanced options are not yet supported on all platforms/browsers. I know they are not used in this example, but just wanted to add for clarity. See MDN for more info
                      – Ayame__
                      Jan 9 '14 at 15:05




                      70




                      70




                      If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
                      – Michael Dyck
                      Jul 30 '14 at 21:47






                      If you're going to involve localeCompare(), you could just use its ability to be case-insensitive, e.g.: return a.localeCompare(b, 'en', {'sensitivity': 'base'});
                      – Michael Dyck
                      Jul 30 '14 at 21:47






                      1




                      1




                      +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                      – Milimetric
                      Sep 12 '14 at 15:26






                      +1 for not calling toLowerCase() when localeCompare already does that by default in some cases. You can read more about the parameters to pass to it here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
                      – Milimetric
                      Sep 12 '14 at 15:26






                      3




                      3




                      @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
                      – 3k-
                      Apr 6 '15 at 14:18




                      @Milimetric accord to the referenced page, that feature is not supported by some browsers (eg. IE<11 or Safari). the solution mentioned here is very good, but would still require backporting/polyfill for some browsers.
                      – 3k-
                      Apr 6 '15 at 14:18




                      1




                      1




                      If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
                      – valtlai
                      Apr 3 '18 at 10:00






                      If you have a large array, it makes sense to use items.sort(new Intl.Collator('en').compare) for better performance. (See MDN.)
                      – valtlai
                      Apr 3 '18 at 10:00















                      57














                      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.






                      share|improve this answer



















                      • 3




                        This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
                        – Jacob
                        Aug 6 '13 at 17:23










                      • True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
                        – ron tornambe
                        Aug 6 '13 at 19:00






                      • 1




                        @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
                        – nothingisnecessary
                        Dec 20 '16 at 21:44
















                      57














                      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.






                      share|improve this answer



















                      • 3




                        This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
                        – Jacob
                        Aug 6 '13 at 17:23










                      • True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
                        – ron tornambe
                        Aug 6 '13 at 19:00






                      • 1




                        @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
                        – nothingisnecessary
                        Dec 20 '16 at 21:44














                      57












                      57








                      57






                      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.






                      share|improve this answer














                      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.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Aug 6 '13 at 19:02

























                      answered Jan 25 '12 at 1:56









                      ron tornambe

                      7,35762545




                      7,35762545








                      • 3




                        This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
                        – Jacob
                        Aug 6 '13 at 17:23










                      • True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
                        – ron tornambe
                        Aug 6 '13 at 19:00






                      • 1




                        @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
                        – nothingisnecessary
                        Dec 20 '16 at 21:44














                      • 3




                        This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
                        – Jacob
                        Aug 6 '13 at 17:23










                      • True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
                        – ron tornambe
                        Aug 6 '13 at 19:00






                      • 1




                        @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
                        – nothingisnecessary
                        Dec 20 '16 at 21:44








                      3




                      3




                      This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
                      – Jacob
                      Aug 6 '13 at 17:23




                      This can call toLowerCase twice on each string; would be more efficient to stored lowered versions of the string in variables.
                      – Jacob
                      Aug 6 '13 at 17:23












                      True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
                      – ron tornambe
                      Aug 6 '13 at 19:00




                      True and thanks. I wrote this with clarity in mind, not performance. I guess I should note that.
                      – ron tornambe
                      Aug 6 '13 at 19:00




                      1




                      1




                      @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
                      – nothingisnecessary
                      Dec 20 '16 at 21:44




                      @Jacob To be fair the accepted answer has same basic problem: it can possibly call .toLowerCase() multiple times for each item in array. For example, 45 calls to the compare function when sorting 10 items in reverse order. var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
                      – nothingisnecessary
                      Dec 20 '16 at 21:44











                      24














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





                      share|improve this answer























                      • or return a === b ? 0 : a > b ? 1 : -1;
                        – Devin G Rhode
                        Dec 4 '17 at 22:46
















                      24














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





                      share|improve this answer























                      • or return a === b ? 0 : a > b ? 1 : -1;
                        – Devin G Rhode
                        Dec 4 '17 at 22:46














                      24












                      24








                      24






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





                      share|improve this answer














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






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Dec 4 '17 at 22:47









                      Devin G Rhode

                      14.3k52543




                      14.3k52543










                      answered Jan 25 '12 at 1:54









                      Niet the Dark Absol

                      256k53356466




                      256k53356466












                      • or return a === b ? 0 : a > b ? 1 : -1;
                        – Devin G Rhode
                        Dec 4 '17 at 22:46


















                      • or return a === b ? 0 : a > b ? 1 : -1;
                        – Devin G Rhode
                        Dec 4 '17 at 22:46
















                      or return a === b ? 0 : a > b ? 1 : -1;
                      – Devin G Rhode
                      Dec 4 '17 at 22:46




                      or return a === b ? 0 : a > b ? 1 : -1;
                      – Devin G Rhode
                      Dec 4 '17 at 22:46











                      18














                      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.






                      share|improve this answer


























                        18














                        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.






                        share|improve this answer
























                          18












                          18








                          18






                          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.






                          share|improve this answer












                          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.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Feb 27 '18 at 9:13









                          ZunTzu

                          4,02112034




                          4,02112034























                              10














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





                              share|improve this answer


























                                10














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





                                share|improve this answer
























                                  10












                                  10








                                  10






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





                                  share|improve this answer












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






                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Sep 26 '14 at 13:43









                                  Aalex Gabi

                                  73411026




                                  73411026























                                      7














                                      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"]





                                      share|improve this answer



















                                      • 3




                                        Screw old browsers; I'm using this.
                                        – Lonnie Best
                                        Feb 4 '18 at 14:27












                                      • This guy gets it
                                        – emptywalls
                                        Aug 6 '18 at 20:46
















                                      7














                                      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"]





                                      share|improve this answer



















                                      • 3




                                        Screw old browsers; I'm using this.
                                        – Lonnie Best
                                        Feb 4 '18 at 14:27












                                      • This guy gets it
                                        – emptywalls
                                        Aug 6 '18 at 20:46














                                      7












                                      7








                                      7






                                      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"]





                                      share|improve this answer














                                      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"]






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Nov 23 '18 at 15:38

























                                      answered Nov 2 '16 at 22:24









                                      mateuscb

                                      4,91633864




                                      4,91633864








                                      • 3




                                        Screw old browsers; I'm using this.
                                        – Lonnie Best
                                        Feb 4 '18 at 14:27












                                      • This guy gets it
                                        – emptywalls
                                        Aug 6 '18 at 20:46














                                      • 3




                                        Screw old browsers; I'm using this.
                                        – Lonnie Best
                                        Feb 4 '18 at 14:27












                                      • This guy gets it
                                        – emptywalls
                                        Aug 6 '18 at 20:46








                                      3




                                      3




                                      Screw old browsers; I'm using this.
                                      – Lonnie Best
                                      Feb 4 '18 at 14:27






                                      Screw old browsers; I'm using this.
                                      – Lonnie Best
                                      Feb 4 '18 at 14:27














                                      This guy gets it
                                      – emptywalls
                                      Aug 6 '18 at 20:46




                                      This guy gets it
                                      – emptywalls
                                      Aug 6 '18 at 20:46











                                      4














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






                                      share|improve this answer


























                                        4














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






                                        share|improve this answer
























                                          4












                                          4








                                          4






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






                                          share|improve this answer












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







                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Jan 25 '12 at 1:54







                                          user1106925






























                                              3














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






                                              share|improve this answer



















                                              • 1




                                                To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                                                – Charles Wood
                                                May 3 '18 at 15:27


















                                              3














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






                                              share|improve this answer



















                                              • 1




                                                To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                                                – Charles Wood
                                                May 3 '18 at 15:27
















                                              3












                                              3








                                              3






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






                                              share|improve this answer














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







                                              share|improve this answer














                                              share|improve this answer



                                              share|improve this answer








                                              edited Nov 21 '15 at 14:51

























                                              answered Oct 1 '14 at 15:55









                                              AndyS

                                              444414




                                              444414








                                              • 1




                                                To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                                                – Charles Wood
                                                May 3 '18 at 15:27
















                                              • 1




                                                To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                                                – Charles Wood
                                                May 3 '18 at 15:27










                                              1




                                              1




                                              To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                                              – Charles Wood
                                              May 3 '18 at 15:27






                                              To be pedantic, this isn't the Elvis operator. This is just a basic ternary operator. A true Elvis operator is null-coalescing, e.g., instead of x = y ? y : z, you can do x = y ?: z. Javascript doesn't have an actual Elvis operator, but you can use x = y || z in a similar fashion.
                                              – Charles Wood
                                              May 3 '18 at 15:27













                                              2














                                              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.






                                              share|improve this answer





















                                              • (''+notdefined) === "undefined" so it'd sort before "z"
                                                – MattW
                                                Sep 14 '16 at 14:34












                                              • @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                                                – John Henckel
                                                Sep 15 '16 at 16:10










                                              • Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                                                – MattW
                                                Sep 15 '16 at 18:05










                                              • And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                                                – MattW
                                                Sep 15 '16 at 18:26






                                              • 1




                                                Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                                                – John Henckel
                                                Sep 15 '16 at 21:09
















                                              2














                                              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.






                                              share|improve this answer





















                                              • (''+notdefined) === "undefined" so it'd sort before "z"
                                                – MattW
                                                Sep 14 '16 at 14:34












                                              • @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                                                – John Henckel
                                                Sep 15 '16 at 16:10










                                              • Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                                                – MattW
                                                Sep 15 '16 at 18:05










                                              • And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                                                – MattW
                                                Sep 15 '16 at 18:26






                                              • 1




                                                Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                                                – John Henckel
                                                Sep 15 '16 at 21:09














                                              2












                                              2








                                              2






                                              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.






                                              share|improve this answer












                                              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.







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Sep 9 '16 at 16:35









                                              John Henckel

                                              3,24813046




                                              3,24813046












                                              • (''+notdefined) === "undefined" so it'd sort before "z"
                                                – MattW
                                                Sep 14 '16 at 14:34












                                              • @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                                                – John Henckel
                                                Sep 15 '16 at 16:10










                                              • Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                                                – MattW
                                                Sep 15 '16 at 18:05










                                              • And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                                                – MattW
                                                Sep 15 '16 at 18:26






                                              • 1




                                                Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                                                – John Henckel
                                                Sep 15 '16 at 21:09


















                                              • (''+notdefined) === "undefined" so it'd sort before "z"
                                                – MattW
                                                Sep 14 '16 at 14:34












                                              • @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                                                – John Henckel
                                                Sep 15 '16 at 16:10










                                              • Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                                                – MattW
                                                Sep 15 '16 at 18:05










                                              • And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                                                – MattW
                                                Sep 15 '16 at 18:26






                                              • 1




                                                Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                                                – John Henckel
                                                Sep 15 '16 at 21:09
















                                              (''+notdefined) === "undefined" so it'd sort before "z"
                                              – MattW
                                              Sep 14 '16 at 14:34






                                              (''+notdefined) === "undefined" so it'd sort before "z"
                                              – MattW
                                              Sep 14 '16 at 14:34














                                              @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                                              – John Henckel
                                              Sep 15 '16 at 16:10




                                              @MattW nope you're wrong. see jsfiddle.net/qrw0uy3r
                                              – John Henckel
                                              Sep 15 '16 at 16:10












                                              Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                                              – MattW
                                              Sep 15 '16 at 18:05




                                              Guess I should've looked up the definition of Array.prototype.sort :| because the part about (''+notdefined) === "undefined" really is true... which means if you flip the -1 and 1 in the sort function to reverse the order, undefined still sorts to the end. It also needs to be considered when using the comparison function outside the context of an array sort (as I was when I came upon this question).
                                              – MattW
                                              Sep 15 '16 at 18:05












                                              And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                                              – MattW
                                              Sep 15 '16 at 18:26




                                              And having now pondered that Array.prototype.sort definition - couple more comments. First, there's no need for the (''+a) - ECMAScript requires toString() to be called on elements prior to passing them into compareFn. Second, the fact that ignoreCase returns 1 when comparing equal (including equal-but-for-case) strings means the specification doesn't define the result if there are duplicate values (will probably be fine just with some unnecessary swaps occurring, I think).
                                              – MattW
                                              Sep 15 '16 at 18:26




                                              1




                                              1




                                              Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                                              – John Henckel
                                              Sep 15 '16 at 21:09




                                              Ah, ok, that makes perfect sense. For undefined the compareFn is never called
                                              – John Henckel
                                              Sep 15 '16 at 21:09











                                              0














                                              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/






                                              share|improve this answer


























                                                0














                                                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/






                                                share|improve this answer
























                                                  0












                                                  0








                                                  0






                                                  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/






                                                  share|improve this answer












                                                  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/







                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Aug 12 '15 at 11:12









                                                  Ian Jamieson

                                                  2,21811644




                                                  2,21811644























                                                      0














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





                                                      share|improve this answer


























                                                        0














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





                                                        share|improve this answer
























                                                          0












                                                          0








                                                          0






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





                                                          share|improve this answer












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






                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered Sep 8 '15 at 10:30









                                                          Envy

                                                          159314




                                                          159314























                                                              0














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





                                                              share|improve this answer


























                                                                0














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





                                                                share|improve this answer
























                                                                  0












                                                                  0








                                                                  0






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





                                                                  share|improve this answer












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






                                                                  share|improve this answer












                                                                  share|improve this answer



                                                                  share|improve this answer










                                                                  answered Mar 31 '17 at 0:07









                                                                  Jason

                                                                  3,0112227




                                                                  3,0112227























                                                                      -2














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






                                                                      share|improve this answer























                                                                      • The question is about sorting, not matching.
                                                                        – Xufox
                                                                        Sep 12 '18 at 20:24
















                                                                      -2














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






                                                                      share|improve this answer























                                                                      • The question is about sorting, not matching.
                                                                        – Xufox
                                                                        Sep 12 '18 at 20:24














                                                                      -2












                                                                      -2








                                                                      -2






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






                                                                      share|improve this answer














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







                                                                      share|improve this answer














                                                                      share|improve this answer



                                                                      share|improve this answer








                                                                      edited Feb 24 '16 at 17:53

























                                                                      answered Oct 13 '15 at 19:05









                                                                      user3225968

                                                                      8319




                                                                      8319












                                                                      • The question is about sorting, not matching.
                                                                        – Xufox
                                                                        Sep 12 '18 at 20:24


















                                                                      • The question is about sorting, not matching.
                                                                        – Xufox
                                                                        Sep 12 '18 at 20:24
















                                                                      The question is about sorting, not matching.
                                                                      – Xufox
                                                                      Sep 12 '18 at 20:24




                                                                      The question is about sorting, not matching.
                                                                      – Xufox
                                                                      Sep 12 '18 at 20:24





                                                                      protected by Pankaj Parkar Oct 19 '15 at 6:24



                                                                      Thank you for your interest in this question.
                                                                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                                      Would you like to answer one of these unanswered questions instead?



                                                                      Popular posts from this blog

                                                                      A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                                                                      Calculate evaluation metrics using cross_val_predict sklearn

                                                                      Insert data from modal to MySQL (multiple modal on website)