2010-11-13 20 views
1

c'est un tableau d'objets que je veux alphabétiser:ActionScript - Array.sortOn() pour les données non anglaises?

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

maintenant, je vais trier mon tableau:

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

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

l'accent au-dessus du E Édouard-Montpetit, ainsi que tout autre premier lettre avec un accent non-anglais est triée après Z.

des idées comment je peux trier correctement? Je n'ai pas accès aux données nommées.

Répondre

2

Je sais ce retard, mais pour ceux qui veulent aller à travers cette réponse, vous pourriez passer un Collator objet à la méthode Array.sort(). Un exemple simple de la documentation:

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é 

Hope this helps

1

Je ne pense pas que vous pouvez le faire avec sortOn, car il n'y a aucun moyen de dire à flash d'utiliser une collation particulière pour le tri du texte (du moins, pas que je sache).

Toutefois, vous pouvez utiliser sort et une fonction de tri personnalisée.

Dans cette fonction de tri, vous souhaitez fondamentalement supprimer tous les accents et effectuer une comparaison insensible à la casse. Remplacement des signes diacritiques est facile et après cela, vous pouvez utiliser en toute sécurité < et > pour comparer les chaînes. Une fonction de tri est appelée par tri avec deux des éléments à trier à la fois. Il devrait renvoyer un nombre négatif si les premiers éléments passés sont tris en premier, un nombre possitif si le second vient en premier et 0 s'ils sont égaux.

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

Un couple de notes à ce sujet. Je sais que cette méthode ne fonctionnera pas pour l'espagnol, car vous avez ñ, qui est considéré comme une lettre à part (pas un n régulier avec une drôle de marque) et vient après n et avant o. Donc, il n'est pas possible de simplement remplacer les accents et faire un </> comparer. Je pense que ce n'est pas un problème en français, mais je peux me tromper (je ne sais pas comment Ç/ç est considéré à des fins de tri, par exemple). De plus, notez que je n'ai pas remplacé tous les signes diacritiques possibles, donc vous voudriez ajouter des circonflexes (^) et des trémas (¨) au replaceDiacritics si nécessaire.

Modifier

Pour une approche basée sur la table, vous pouvez essayer quelque chose comme ce qui suit. Chaque lettre reçoit un numéro qui reflète l'ordre de tri. Tant que vous pouvez supposer qu'une lettre aura un ordre de tri absolu (c'est-à-dire que le contexte ne changera pas comment cela fonctionne, ce qui n'est pas le cas dans certaines langues), cela devrait vous donner de bons résultats. Par la paresse, j'ai construit la table avec une boucle et j'ai fait ce qui était nécessaire pour mettre "Ñ" entre "n" et "o". Je ne considère aucun signe diacritique à des fins de tri, donc ils ont la même valeur que leur contrepartie non accentuée. Mais vous pouvez changer cette table comme nécessaire. Aussi, cette table devrait probablement être codée en dur pour les paramètres régionaux requis, mais ce code est juste pour vous donner une idée de la façon dont vous pourriez faire cela, pas une implémentation complète (et ce n'est probablement pas tout à fait correct du point de vue puriste pourrait faire le travail). De plus, si nous trouvons un caractère qui n'est pas mappé, je retombe sur son point de code pour déterminer comment il trie.

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

cela est très utile. Merci beaucoup. mes tests montrent que "ç", et tous les autres signes diacritiques en français sont triés après "z". d'intérêt, l'accent aigu: é est toujours trié avant l'accent grave: è. Je me demande si cette exclusion des diacritiques linguistiques est intentionnelle. Peut-être que cela devrait être signalé comme une demande de bug ou de fonctionnalité. – TheDarkIn1978

+0

également, en triant les graphèmes, comme æ et œ, ne pas trier correctement. mais c'est probablement trop pour les inclure de toute façon. – TheDarkIn1978

+0

Pas de problème. Je pense que la méthode ci-dessus pourrait être assez bonne, mais ce n'est pas parfait, c'est sûr. Peut-être pourrait-on l'ajuster pour de meilleurs résultats, mais cela nécessite de savoir comment fonctionne le tri en français (ce que je ne connais pas). Si ç doit trier après z, vous ne pouvez pas le remplacer dans la fonction de remplacement des diacritiques. Si æ et œ sont équivalents pour le tri ae et oe, alors je pense que vous pourriez les ajouter dans la fonction de remplacement (donc æ est converti en ae). En ce qui concerne l'ordre des signes diacritiques, s'il est important que á précède avant, alors vous devriez probablement changer le code pour utiliser une approche basée sur une table. –