【问题标题】:ActionScript - Array.sortOn() For Non-English Data?ActionScript - Array.sortOn() 用于非英语数据?
【发布时间】:2010-11-13 19:32:00
【问题描述】:

这是我要按字母顺序排列的对象数组:

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 之后。

任何想法我可以如何正确排序?我无权访问命名数据。

【问题讨论】:

    标签: arrays actionscript-3 sorting non-english


    【解决方案1】:

    我知道这已经晚了,但是对于任何通过此答案的人,您可以传递 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é 
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      我不认为你可以用 sortOn 做到这一点,因为没有办法告诉 flash 使用特定的排序规则对文本进行排序(至少,我不知道)。

      但是,您可以使用 sort 和自定义排序函数。

      在这个排序函数中,基本上你想去掉所有的重音并进行不区分大小写的比较。替换变音符号很容易,之后,您可以安全地使用<> 来比较字符串。排序函数通过 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 之前。因此,不可能只替换重音符号并进行 &lt; / &gt; 比较。我认为这在法语中不是问题,但我可能是错的(例如,不确定如何考虑 Ç / ç 用于排序目的)。另外请注意,我没有替换所有可能的变音符号,因此您需要根据需要在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'accent aigu: é 总是排在 l'accent grave: è 之前。我想知道这种排除语言变音符号是否是设计使然。也许这应该报告为错误或功能请求。
      • 另外,排序字素,如 æ 和 œ,排序不正确。但无论如何都包括这些可能有点矫枉过正。
      • 没问题。我认为上述方法可能已经足够好了,但肯定不是完美的。也许可以对其进行调整以获得更好的结果,但这需要了解法语排序的工作原理(我不知道)。如果 ç 必须在 z 之后排序,那么您不能在替换变音符号函数中替换它。如果 æ 和 – 在排序目的上等同于 ae 和 oe,那么我认为您可以将它们添加到替换函数中(因此 æ 被转换为 ae)。至于变音符号的顺序,如果 á 在 à 之前很重要,那么您可能应该更改代码以使用基于表格的方法。
      • (续)。我知道在西班牙语中这并不重要,因为我们只有尖锐的口音和 ü。例如,可能“sabia”(sap 或 wise [feminine])出现在“sabía”([he/she/it/formal single you] know)之前。但在实践中,这不是一个真正的问题(同样,在西班牙语中,从母语人士的角度来看,而不是排序、校对等方面的专家)。我认为播放器中没有错误。这只是一个二进制排序,所以字符是根据它们的数字代码点排序的。不过,如果您可以设置排序规则,这样结果对于非英语语言环境更有意义,那就太好了。
      • @TheDarkInI1978。我添加了一些代码来向您展示如何实现基于表格的排序。
      猜你喜欢
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-19
      • 2014-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多