2010-11-13 31 views
1

這是我想按字母順序排列對象的數組:ActionScript - Array.sortOn()對於非英文數據?

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 

的口音愛德華-Montpetit對E以上,和任何其他第一帶有非英語口音的信件按Z排序。

任何想法如何我可以正確地排序?我無法訪問指定的數據。

回答

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

我不認爲你可以用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; 
    } 
} 
+0

這是非常有幫助的。非常感謝你。我的測試顯示「ç」以及法語中的所有其他變音符號都按「z」排序。感興趣的人,l'口音aigu:é總是在l'口音之前排序:è。我想知道這種語言變音符的排除是否由設計決定。也許這應該被報告爲錯誤或功能請求。 – TheDarkIn1978 2010-11-14 09:54:44

+0

也排序字形,如æ和œ,排序不正確。但它可能矯枉過正,包括那些。 – TheDarkIn1978 2010-11-14 10:23:31

+0

沒問題。我認爲上述方法可能足夠好,但當然不完美。也許它可以調整以獲得更好的結果,但這需要了解如何在法語中進行排序(我不知道)。如果ç必須在z之後排序,那麼在替換區分符號函數中就不能替換它。如果æ和œ對於ae和oe的排序目的是等價的,那麼我認爲你可以將它們添加到替換函數中(所以æ被轉換爲ae)。至於變音符號順序,如果á在à之前出現很重要,那麼您應該更改代碼以使用基於表格的方法。 – 2010-11-14 14:37:07