使用自定义比较函数(对数字数字和文本字母数字进行排序)对数据网格进行弹性排序



我需要以下结果。

所有数字都使用数字排序

,所有字符串都使用字母数字排序。此外,数值应该列在字符串值之前:

例:在"i","9","89","0045","b","x"之前

在"9","0045","89","b","i","x" 之后

我当前的代码如下所示:(数字排序有效,但我的字符串分布在顶部和底部?! ->"b","x","9","0045","89","i")

 public function compareFunction(obj1:Object, obj2:Object):int {
  var id1:String = (obj1 as WdProblem).id;
  var id2:String = (obj2 as WdProblem).id;
  if(id1.replace(' ', '') == "n") {
    var sdld:int = 0;
  }
  var num1:int = Number(id1);
  var num2:int = Number(id2);
  if(stringIsAValidNumber(id1) && stringIsAValidNumber(id2)) {
    if(num1 == num2) {
      return 0;
    } else {
      if(num1 > num2) {
        return 1;
      } else {
        return -1;
      }
    }
  } else if(!stringIsAValidNumber(id1) && !stringIsAValidNumber(id2)) {
    return ObjectUtil.compare(id1, id2);
      //return compareString(id1, id2);
  } else if(!stringIsAValidNumber(id1) && stringIsAValidNumber(id2)) {
    return 1;
  } else if(stringIsAValidNumber(id1) && !stringIsAValidNumber(id2)) {
    return -1;
  }
  return -1;
}
private function stringIsAValidNumber(s:String):Boolean {
  return Boolean(s.match("[0-9]+(.[0-9][0-9]?)?"));
}

我的建议是将其分解为它的组成部分,特别是如果您有这样的具有 1 个或多个优先级排序的场景。关键是只有在第一个排序返回它们相等时才进入下一个排序。

对于您的情况,我会构建 2 种排序,一种用于数字,另一种用于字母数字,然后您的主排序可以通过调用子排序来优先考虑这些排序。

例如,我有类似的东西:

private function sort2DimensionsByIncomeVsTime(a:OLAPSummaryCategory, b:OLAPSummaryCategory, fields:Array = null):int
{
    var sort:OLAPSort = new OLAPSort();
    var incomeSort:int = sort.sortIncome(a, b);
    var nameSort:int = sort.sortName(a, b);
    var yrSort:int = sort.sortYear(a, b);
    var moSort:int = sort.sortMonth(a, b);
    if (incomeSort == 0)
    {
        if (nameSort == 0)
        {
           if (yrSort == 0) 
           {
               //trace(a.name, a.year, a.month, 'vs:', b.name, b.year, b.month, 'month sort:', moSort);
               return moSort;
           }
           else return yrSort;
        }
        else return nameSort;
    }
    else return incomeSort;
}

我使用以下排序函数进行字母数字排序:

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    creationComplete="onCC()"
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.utils.ObjectUtil;
            import mx.utils.StringUtil;
            import spark.collections.Sort;
            import spark.collections.SortField;
            public function onCC():void
            {
                var acAlphaNumericString:ArrayCollection = new ArrayCollection();
                acAlphaNumericString.addItem({ name: "NUM10071" });
                acAlphaNumericString.addItem({ name: "NUM9999" });
                acAlphaNumericString.addItem({ name: "9997" });
                acAlphaNumericString.addItem({ name: "9998" });
                acAlphaNumericString.addItem({ name: "9996" });
                acAlphaNumericString.addItem({ name: "9996F" });
                acAlphaNumericString.addItem({ name: "i" });
                acAlphaNumericString.addItem({ name: "9" });
                acAlphaNumericString.addItem({ name: "89" });
                acAlphaNumericString.addItem({ name: "0045" });
                acAlphaNumericString.addItem({ name: "b" });
                acAlphaNumericString.addItem({ name: "x" });
                var sf:SortField = new SortField("name");
                sf.compareFunction = function(o1:Object, o2:Object):int
                {
                    return compare(o1.name, o2.name);
                }
                var sort:Sort = new Sort();
                sort.fields = [ sf ];
                acAlphaNumericString.sort = sort;
                acAlphaNumericString.refresh();
                for each (var o:Object in acAlphaNumericString)
                    trace(o.name);
            }
            public static function compare(firstString:String, secondString:String):int
            {
                if (secondString == null || firstString == null)
                    return 0;
                var lengthFirstStr:int = firstString.length;
                var lengthSecondStr:int = secondString.length;
                var index1:int = 0;
                var index2:int = 0;
                while (index1 < lengthFirstStr && index2 < lengthSecondStr)
                {
                    var ch1:String = firstString.charAt(index1);
                    var ch2:String = secondString.charAt(index2);
                    var space1:String = "";
                    var space2:String = "";
                    do
                    {
                        space1 += ch1;
                        index1++;
                        if (index1 < lengthFirstStr)
                            ch1 = firstString.charAt(index1);
                        else
                            break;
                    } while (isDigit(ch1) == isDigit(space1.charAt(0)));
                    do
                    {
                        space2 += ch2;
                        index2++;
                        if (index2 < lengthSecondStr)
                            ch2 = secondString.charAt(index2);
                        else
                            break;
                    } while (isDigit(ch2) == isDigit(space2.charAt(0)));
                    var str1:String = new String(space1);
                    var str2:String = new String(space2);
                    var result:int;
                    if (isDigit(space1.charAt(0)) && isDigit(space2.charAt(0)))
                    {
                        var firstNumberToCompare:int = parseInt(StringUtil.trim(str1));
                        var secondNumberToCompare:int = parseInt(StringUtil.trim(str2));
                        result = ObjectUtil.numericCompare(firstNumberToCompare, secondNumberToCompare);
                    }
                    else
                        result = ObjectUtil.compare(str1, str2);
                    if (result != 0)
                        return result;
                }
                return lengthFirstStr - lengthSecondStr;
                function isDigit(ch:String):Boolean
                {
                    var code:int = ch.charCodeAt(0);
                    return code >= 48 && code <= 57;
                }
            }
        ]]>
    </fx:Script>
</s:Application>

相关内容

  • 没有找到相关文章

最新更新