这是我想要按字母顺序排列的对象数组:
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
Édouard-Montpetit中E上方的重音,任何其他带有非英语口音的首字母在Z之后排序。
任何想法我怎么能正确排序?我无法访问指定的数据。
答案 0 :(得分:2)
我知道这已经很晚了,但是对于任何通过这个答案的人来说,你都可以通过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 :(得分:1)
我认为你不能用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;
}
}