使用JavaScript按字母顺序排序丹麦语?

5

有没有JavaScript的库或跨浏览器本地实现来按字母顺序对丹麦字符串数组进行排序?

[奥尔堡,索罗...]

2个回答

6
您可以使用以下方法在Chrome和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);

为了更加兼容各种浏览器,你可以选择以下两种方案之一: 1. 修正localeCompare函数(或者只为丹麦语替换它)。 2. 修改整个排序算法。
针对这个任务,我会使用类似于桶排的算法,理论上比默认排序更快(它会减少最小的比较次数)。
大致思路是遍历每个字符串,并按照首字母将其放入相应的(已排序)桶中。然后,根据第二个字母、第三个字母等继续将至少包含两个字符串的桶分割。最后合并所有桶即可得到排序好的数组。

只能在Chrome中使用,是否有跨浏览器的实现或库?(在FF中未实现选项参数) - dani
它在Chrome上也不起作用,至少在我的Ubuntu版本18.0.1025.168上不起作用。但无论如何,我们应该期望它能够正常工作(但是丹麦字母总是会有问题 :))。 - davidkonrad
如果你说的是它似乎将它们倒序排序,我也感到困惑,但后来我意识到它以某种方式认为 aa > s。算了吧,我不太了解丹麦语来弄清所有的排序规则。 - Tibos
我本以为你的解决方案也可以工作,但它似乎只将特殊字母视为"a"。对于排序丹麦字母,即使是对于数据库、文字处理器等,一直都是一个问题,所以我并不惊讶你的好答案失败了。不过它可能适用于法语和德语字符 :) - davidkonrad
使用箭头函数: arr.sort((a,b) => a.localeCompare(b, myLocale)); - Eneko

6

很遗憾,@Tibos的解决方案不起作用。丹麦字母 æøå 的排序结果与丹麦人的期望不符。而使用 aa 也肯定行不通,因为它被认为是一种老式的 å。唯一的解决办法是制定一个“手持式”排序算法。

以下是可行的解决方案:

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

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

按照本地排序

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

这是完全错误的。上述函数正确地对数组进行了排序:
["Almindingen", "Sorø", "Ærø", "Ølby", "Ålestrup", "Aalborg"]

更新

@tibos是正确的。上述算法只是按照首字母排序。下面的函数将字符串转换为整数数组,根据上述算法中的排序方案。然后比较整数数组 - 通过这种方式,字符串按其完整长度进行排序:

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

测试数组:

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

现在已经完整地排序:

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

不错的回答,但你可能想要扩展它以支持此文档中列出的所有规则(我猜这是官方标准)。 - georg
你显然对丹麦语言有足够的了解,可以实现一个正确的比较函数。不过现在你的函数似乎只看第一个字符,但我想这只是一个小疏忽。 - Tibos
已经制作了一个更干净的版本,并提供了一些处理 aa 的选项和测试脚本 -> https://github.com/davidkonrad/sortda - davidkonrad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接