Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort Danish alphabetically using JavaScript?

Is there a library or cross-browser native implementation to sort an array of Danish strings alphabetically in JavaScript?

[Aalborg, Sorø ...]

like image 332
dani Avatar asked Dec 20 '22 20:12

dani


2 Answers

Unfortunately @Tibos solution doesnt work. The danish letters æøå is not sortable as a dane would expect. And it certainly wont work with aa, which is considered as an oldschool å. The only solution is to make an "handheld" sort-algorithm.

Here is working solution :

arr.sort(function(a,b) {
    function getCode(c) {
        c=c.toLowerCase();
        if (c.substring(0,2)=='aa') return 300; 
        switch (c.charCodeAt(0)) {
            case 229 : //å
                return 299;
                break;
            case 248 : //ø
                return 298;
                break;
            case 230 : //æ
                return 297;
                break;
            default : 
                return c.charCodeAt(0);
                break;
        }
    }
    return getCode(a) - getCode(b);
});

The test array

var arr = ['Ølby', 'Ålestrup', 'Ærø', 'Almindingen', 'Aalborg', 'Sorø'];

is by locale sorted as

["Ølby", "Ærø", "Ålestrup", "Sorø", "Almindingen", "Aalborg"]

Which is totally wrong. The above function sort the array correct :

["Almindingen", "Sorø", "Ærø", "Ølby", "Ålestrup", "Aalborg"]

Update

@tibos was absolutely right. The above algorithm just sort by the first letter. The below function converts the strings to array of integers, according to the sorting-scheme from the algorithm above. Then it compares the integer arrays - by that, the strings are sorted in their full length :

arr.sort(function(a,b) {
    var d, e, f;
    function getIntArray(c) {
        var array=[];
        c=c.toLowerCase();
        for (var i=0;i<c.length;i++) {
            if (c.substring(i,2)=='aa') {
                array.push(300); 
                i++;
            } else {
                switch (c.charCodeAt(i)) {
                    case 229 : //å
                        array.push(299);
                        break;
                    case 248 : //ø
                        array.push(298);
                        break;
                    case 230 : //æ
                        array.push(297);
                        break;
                    default : 
                        array.push(c.charCodeAt(i));
                        break;
                }
            }
        }
        return array;
    }
    d=getIntArray(a);
    e=getIntArray(b);
    for (f=0;f<d.length;f++) {
        if (d[f]!=e[f]) {
            return d[f] - e[f];
        }
    }
});

test array :

var arr = ['Ølby', 'Ålborg', 'Århus', 'Ålestrup', 'Åkikrkeby', 'Ærø', 'Almindingen', 'Aalborg', 'Sorø'];

is now sorted in full length :

["Almindingen", "Sorø", "Ærø", "Ølby", "Åkikrkeby", "Ålborg", "Ålestrup", "Århus", "Aalborg"]
like image 127
davidkonrad Avatar answered Jan 04 '23 23:01

davidkonrad


You can use the following method to sort strings in any language in Chrome and IE11:

var arr = ['Aalborg', 'Sorø']; // array to sort
var myLocale = 'da-DK'; // danish locale

var sortedArr = arr.sort(function(a,b) { return a.localeCompare(b, myLocale); }); // sort

console.log(sortedArr);

For a more browser agnostinc solution, you have two options:

  1. shim the localeCompare function (or replace it with one only for danish)
  2. change the whole sorting algorithm

For this task i would use a bucket-sort-like algorithm that should in theory run faster than the default sort (it would make the minimal number of comparisons).

The general idea is that you go through each string, place them in (sorted) buckets according to the first letter. You continue to split each bucket containing at least 2 strings according to the second letter, then the third and so on. At the end you merge the buckets and you have the sorted array.

like image 42
Tibos Avatar answered Jan 04 '23 23:01

Tibos