我不認爲你可以用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;
}
}
這是非常有幫助的。非常感謝你。我的測試顯示「ç」以及法語中的所有其他變音符號都按「z」排序。感興趣的人,l'口音aigu:é總是在l'口音之前排序:è。我想知道這種語言變音符的排除是否由設計決定。也許這應該被報告爲錯誤或功能請求。 – TheDarkIn1978 2010-11-14 09:54:44
也排序字形,如æ和œ,排序不正確。但它可能矯枉過正,包括那些。 – TheDarkIn1978 2010-11-14 10:23:31
沒問題。我認爲上述方法可能足夠好,但當然不完美。也許它可以調整以獲得更好的結果,但這需要了解如何在法語中進行排序(我不知道)。如果ç必須在z之後排序,那麼在替換區分符號函數中就不能替換它。如果æ和œ對於ae和oe的排序目的是等價的,那麼我認爲你可以將它們添加到替換函數中(所以æ被轉換爲ae)。至於變音符號順序,如果á在à之前出現很重要,那麼您應該更改代碼以使用基於表格的方法。 – 2010-11-14 14:37:07