flutterdartsortingalphabetical-sortturkish

Sorting strings with Turkish alphabetical order in Dart


I want to sort the Turkish name of countries in Dart, however I couldn't find a method to customize the alphabetical order during sorting operation like collations in Java.

For example when I sort with a standard string compareTo method I get:

var countries = ["Belgrad", "Belçika", "Irak", "İran", "Sudan", "Şili", "Çek Cumhuriyeti", "Cezayir", "Ukrayna", "Ürdün"];

countries.sort((firstString, secondString) => firstString.compareTo(secondString));
print(countries); 

It prints in a wrong order based on English alphabetical order:

[Belgrad, Belçika, Cezayir, Irak, Sudan, Ukrayna, Çek Cumhuriyeti, Ürdün, İran, Şili]

Because in Turkish alphabet the order of letters is "a", "b", "c", "ç", "d", "e", "f", "g", "ğ", "h", "ı", "i", "j", "k", "l", "m", "n", "o", "ö", "p", "r", "s", "ş", "t", "u", "ü", "v", "y", "z", the correct order should be like: (note that Belçika must come before Belgrad because ç < g in Turkish)

[Belçika, Belgrad, Cezayir, Çek Cumhuriyeti, Irak, İran, Sudan, Şili, Ukrayna, Ürdün]


Solution

  • You can define what sorting method you want. If I take your example, you can do something like:

    void main() {
      const List<String> turkishOrder = ["a", "b", "c", "ç", "d", "e", "f", "g", "ğ", "h", "ı", "i", "i̇", "j", "k", "l", "m", "n", "o", "ö", "p", "r", "s", "ş", "t", "u", "ü", "v", "y", "z"];
      List<String> countries = ["Irak", "İran", "Sudan", "Şili", "Çek Cumhuriyeti", "Cezayir", "Ukrayna", "Ürdün"];
    
      countries.sort((String a, String b) => turkishOrder.indexOf(a[0].toLowerCase()).compareTo(turkishOrder.indexOf(b[0].toLowerCase())));
      
      print(countries);
    }
    

    What I did here:

    Notes:

    Edit: the solution above only compares the first letter. Here is an updated version of the comparison function, to compare all letters:

      countries.sort((String a, String b) {
        int index = 0;
        while (index < a.length && index < b.length) {
          final int comparison =
              turkishOrder.indexOf(a[index].toLowerCase()).compareTo(turkishOrder.indexOf(b[index].toLowerCase()));
          if (comparison != 0) {
            // -1 or +1 means that the letters are different, thus an order is found
            return comparison;
          } // 0 means that the letters are equal, go to next letter
          index++;
        }
        return 0;
      });