【问题标题】:Flex sort Datagrid with custom compareFunction (sort numbers numerical and text alphanumerical)使用自定义 compareFunction 对 Datagrid 进行 Flex 排序(数字排序数字和文本字母数字)
【发布时间】:2012-11-23 10:50:39
【问题描述】:

我需要以下结果。

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

示例: 在 "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]?)?"));
}

【问题讨论】:

  • 也许您想为您的问题添加一些前言,以便为您正在尝试做的事情提供一些背景信息。

标签: apache-flex sorting datagrid compare


【解决方案1】:

我的建议是将其分解为各个组成部分,尤其是当您遇到具有 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;
}

【讨论】:

    【解决方案2】:

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

    <?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>
    

    【讨论】:

      猜你喜欢
      • 2011-07-08
      • 1970-01-01
      • 2012-04-26
      • 2014-02-03
      • 1970-01-01
      • 2015-10-14
      • 2016-08-13
      • 2013-08-02
      相关资源
      最近更新 更多