40

There are a lot of examples for sorting some JSON array by some property (i.e. 'title') We are using compare function like this one:

function sortComparer(a, b) {
        if (a.title == b.title)
            return 0;
        return a1 > b1 ? 1 : -1;
    }

Problem is that Serbian Latin alphabet order looks like "A, B, C, Č, Ć, D,..." When using sortComparer above I am getting D sorted before "Č" or "Ć". Any idea how to sort respecting current culture language?

Andrej Kaurin
  • 11,592
  • 13
  • 46
  • 54
  • One way would be to replace the other characters with their ASCII equivalent. – Felix Kling Aug 02 '11 at 08:25
  • Not sure what you think. Only way I am getting on my mind is to define array of letters like: var letters = {'a','b','c', 'č','ć', ...} and in sortComparer function compare indexes. Disadvantage of this approach is that we have to write such array for each culture that is not english. – Andrej Kaurin Aug 02 '11 at 08:43
  • 1
    Javascript does not support the Unicode Collation Algorithm, so you’re basically hosed. You cannot use a code point sort and get anything reasonable. To get an alphabetical sort, you need the UCA. – tchrist Aug 16 '11 at 01:34
  • I think your expected order is wrong. There is an example https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator#using_options –  Aug 04 '21 at 11:06

3 Answers3

64

If the locale in your system is set correctly then you can use localeCompare method instead of greater-than operator to compare the strings - this method is locale aware.

function sortComparer(a,b){
    return a.title.localeCompare(b.title)
};
Andris
  • 27,649
  • 4
  • 34
  • 38
  • 4
    This will work only if locale is set. Any method to pass culture together with compared value? – Andrej Kaurin Aug 02 '11 at 09:14
  • 2
    There's no way to set the locale by script, it is defined by the browser or - depending from the browser - inherited from the OS. – Andris Aug 02 '11 at 09:27
  • 3
    I have found full solution here http://stackoverflow.com/questions/3630645/how-to-compare-utf-8-strings-in-javascript – Andrej Kaurin Feb 21 '12 at 08:47
  • 4
    Be aware that the `localeCompare` function is a lot heavier to run than just comparing strings using `<`, `>`, and `=` operators. Even starting at a result set of 500, there's a significant slow-down using `localeCompare`. As illustrated here, it is slower by a factor of up to 400: https://jsfiddle.net/L4715qey/ – Kafoso Feb 01 '16 at 08:50
  • how about desc sorting? – Dominik Wilga May 18 '20 at 11:01
  • Returned value is a number, so to reverse ordering use - sign. – Andris Jun 13 '20 at 03:24
5

For sorting an array with a custom setting do as following:

  1. Create an array with a custom order of alphabets:

    var alphabets = ["A", "B", "C", "Č", "Ć", "D","Dž","Đ","E","F","G","H","I","J","K","L","Lj","M","N","Nj","O","P","R","S", "ÛŒ","T","U","V","Z","Ž"];

  2. Create a list of test array:

    var testArrray = ["B2","D6","A1","Ć5","Č4","C3"];

  3. Create a sort function name:

    function OrderFunc(){
              testArrray.sort(function (a, b) {
                  return CharCompare(a, b, 0);
              });
          }
    
  4. create the CharCompare function(index: sort "AAAB" before "AAAC"):

     function CharCompare(a, b, index) {
      if (index == a.length || index == b.length)
          return 0;
      //toUpperCase: isn't case sensitive
      var aChar = alphabets.indexOf(a.toUpperCase().charAt(index));
      var bChar = alphabets.indexOf(b.toUpperCase().charAt(index));
      if (aChar != bChar)
          return aChar - bChar
      else
          return CharCompare(a,b,index+1)
     }
    
  5. Call OrderFunc for sorting the testArray(the result will be : A1,B2,C3,Č4,Ć5,D6).

Test Online

Good Luck

Iman Bahrampour
  • 6,180
  • 2
  • 41
  • 64
  • @TheChetan. this is a custom order function and you can manage all the alphabets that you are going to sort. for example, Russian alphabet has 33 chars, Persian has 32 chars and so on. – Iman Bahrampour Oct 09 '17 at 02:04
3

Use The Intl.Collator like you will get perfect sorting result

function letterSort(lang, letters) {
  letters.sort(new Intl.Collator(lang).compare);
  return letters;
}

console.log(letterSort('gu', ['છ','ક','ખ']));
// expected output: Array ["a", "ä", "z"]

console.log(letterSort('sv', ['a','z','ä']));
// expected output: Array ["a", "z", "ä"]

More detail you can check here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator

Dinesh Rabara
  • 1,119
  • 12
  • 13