ActionScript - Array.sortOn () для неанглийских данных? - PullRequest
1 голос
/ 13 ноября 2010

это массив объектов, которые я хочу алфавитировать:

var streets:Array = new Array();
streets.push({name:"Édouard-Montpetit"});
streets.push({name:"Alexandre de Sève"});
streets.push({name:"Van Horne"});
streets.push({name:"Atwater"});

Теперь я отсортирую мой массив:

streets.sortOn("name", Array.CASEINSENSITIVE);

//Sorted
Alexandre de Sève
Atwater
Van Horne
Édouard-Montpetit

ударение над буквой E в Édouard-Montpetit и любые другие первые буквы с неанглийским акцентом сортируются после Z.

есть идеи, как мне правильно это отсортировать? у меня нет доступа к указанным данным.

Ответы [ 2 ]

2 голосов
/ 16 июля 2014

Я знаю, что уже поздно, но для любого, кто проходит через этот ответ, вы можете передать объект Collator в метод Array.sort ().Простой пример из документации:

 var words:Array = new  Array("coté", "côte"); 
 var sorter:Collator = new Collator("fr-FR", CollatorMode.SORTING); 
 words.sort(sorter.compare); 
 trace(words);// côte,coté 

Надеюсь, это поможет

1 голос
/ 14 ноября 2010

Я не думаю, что вы можете сделать это с помощью sortOn, так как нет способа указать flash использовать определенный коллапс для сортировки текста (по крайней мере, я об этом не знаю).

Однако вы можете использовать sort и пользовательскую функцию сортировки.

В этой функции сортировки в основном вы хотите убрать все акценты и выполнить сравнение без учета регистра. Заменить диакритические знаки легко, и после этого вы можете безопасно использовать < и > для сравнения строк. Функция сортировки вызывается по сортировке с двумя элементами, которые должны быть отсортированы одновременно. Он должен возвращать отрицательное число, если первый пропущенный элемент сортирует первым, возможное число, если второй идет первым, и 0, если они сортируются одинаково.

function sortText(obj1:Object,obj2:Object):int {
    var a:String = replaceDiacritics(obj1.name);
    var b:String = replaceDiacritics(obj2.name);

    if(a < b) {
        return -1;
    } else if(b < a) {
        return 1;
    } else {
        return 0;
    }
}

function replaceDiacritics(str:String):String {
    str = str.toLowerCase();
    str = str.replace(/á/g,"a");
    str = str.replace(/é/g,"e");
    str = str.replace(/í/g,"i");
    str = str.replace(/ó/g,"o");
    str = str.replace(/ú/g,"u");

    str = str.replace(/à/g,"a");
    str = str.replace(/è/g,"e");
    str = str.replace(/ì/g,"i");
    str = str.replace(/ò/g,"o");
    str = str.replace(/ù/g,"u");

    return str;
}

streets.sort(sortText);

Несколько замечаний по этому поводу. Я знаю, что этот метод не будет работать для испанского языка, так как у вас есть ñ, который считается буквой сам по себе (не обычный n со смешным знаком) и идет после n и до o. Таким образом, невозможно просто заменить акценты и сделать сравнение < / >. Я думаю, что это не проблема по-французски, но я могу ошибаться (например, я не уверен, как Ç / ç рассматривается для целей сортировки). Кроме того, обратите внимание, что я не заменил все возможные диакритические знаки, поэтому вы хотите добавить окружности (^) и умлауты (¨) к replaceDiacritics при необходимости.

Редактировать

Для табличного подхода вы можете попробовать что-то вроде следующего. Каждой букве присваивается номер, который отражает порядок сортировки. Если вы можете предположить, что любая буква будет иметь абсолютный порядок сортировки (т. Е. Контекст не изменит того, как это работает, чего нельзя сказать о некоторых языках), это должно дать вам хорошие результаты.

Из-за лени я построил таблицу с помощью петли и просто сделал то, что было необходимо, чтобы поставить «С» между «n» и «o». Я не рассматриваю никаких диакритических знаков в целях сортировки, поэтому они имеют ту же ценность, что и их безударный аналог. Но вы можете изменить эту таблицу как необходимую. Кроме того, эта таблица, вероятно, должна быть жестко задана для требуемой локали, но этот код просто для того, чтобы дать вам представление о том, как вы могли бы сделать это, а не в полной реализации (и, вероятно, она не совсем корректна с точки зрения пуристов, но я думаю, что это мог сделать работу). Кроме того, в случае, если мы находим символ, который не отображается, я возвращаюсь к его кодовой точке, чтобы определить, как он сортируется.

var sortTable: Object = buildSortTable ();

function buildSortTable():Object {
    var sortTable:Object = {};
    var char:String;
    var offset:int = 0;
    for(var i:int = 1; i < 256; i++) {
        char = String.fromCharCode(i);
        if(char == "Ñ" || char == "ñ") {
            offset--;
            continue;
        }
        sortTable[char] = i + offset;

        if(char == "N") {
            sortTable["Ñ"] = sortTable["N"] + 1;
            offset++;
        }
        if(char == "n") {
            sortTable["ñ"] = sortTable["n"] + 1;
            offset++;
        }

    }

    sortTable["Á"] = sortTable["À"] = sortTable["Ä"] = sortTable["Â"] = sortTable["A"];
    sortTable["É"] = sortTable["È"] = sortTable["Ë"] = sortTable["Ê"] = sortTable["E"];
    sortTable["Í"] = sortTable["Ì"] = sortTable["Ï"] = sortTable["Î"] = sortTable["I"];
    sortTable["Ó"] = sortTable["Ò"] = sortTable["Ö"] = sortTable["Ô"] = sortTable["O"];
    sortTable["Ú"] = sortTable["Ì"] = sortTable["Ü"] = sortTable["Û"] = sortTable["U"];

    sortTable["á"] = sortTable["à"] = sortTable["ä"] = sortTable["â"] = sortTable["a"];
    sortTable["é"] = sortTable["è"] = sortTable["ë"] = sortTable["ê"] = sortTable["e"];
    sortTable["í"] = sortTable["ì"] = sortTable["ï"] = sortTable["î"] = sortTable["i"];
    sortTable["ó"] = sortTable["ò"] = sortTable["ö"] = sortTable["ô"] = sortTable["o"];
    sortTable["ú"] = sortTable["ù"] = sortTable["ü"] = sortTable["û"] = sortTable["u"];

    return sortTable;
}

function sortText(obj1:Object,obj2:Object):int {

    var a:String = obj1.name.toLowerCase();
    var b:String = obj2.name.toLowerCase();

    var len_a:int = a.length;
    var len_b:int = b.length;

    var char_a:String;
    var char_b:String;

    var val_a:Number;
    var val_b:Number;

    for(var i = 0; i < len_a && i < len_b; i++) {
        char_a = a.charAt(i);
        char_b = b.charAt(i);

        val_a = sortTable[char_a];
        val_b = sortTable[char_b];
        //  this is just in case we have a letter that we haven't mapped...
        //  let's fall back to using its code point
        if(isNaN(val_a)) {
            val_a = char_a.charCodeAt(0);
        }
        if(isNaN(val_b)) {
            val_b = char_b.charCodeAt(0);
        }

        if(val_a < val_b) {
            return -1;
        } else if(val_a > val_b) {
            return 1;
        }
    }
    // both strings are equal so far; so the sorter one (if any) must sort first
    if(len_a < len_b) {
        return -1;
    } else if(len_a > len_b) {
        return 1;
    } else {
        return 0;
    }
}
...