0

我有一个包含两列的 AdvancedDatagrid:代码(字符串)和值(数字)。我对每一列使用相同的排序功能。我想要做的是根据 Value 列(数字数据)对两列进行排序,但是在没有可用数字的情况下,我希望对 Code 列按字母顺序进行排序。

我用一个例子简化了我面临的问题,以代表我正在尝试做的事情:

图片显示了两列,两列的排序均基于 Value 列。如果值为 NaN,我希望 Code 列值按字母顺序排序。所以一、二、三、四将保持不变,但 BADC 将是 ABCD。

在此处输入图像描述

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
                layout="absolute" minWidth="955" minHeight="600" initialize="initializeHandler(event)">

    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;
            import mx.utils.ObjectUtil;

            [Bindable]
            private var ac:ArrayCollection;

            protected function initializeHandler(event:FlexEvent):void
            {
                ac = new ArrayCollection();

                var one:NameValueObject = new NameValueObject("One", 1);
                var two:NameValueObject = new NameValueObject("Two", 2);
                var three:NameValueObject = new NameValueObject("Three", 3);
                var four:NameValueObject = new NameValueObject("Four", 4);
                var a:NameValueObject = new NameValueObject("A", NaN);
                var b:NameValueObject = new NameValueObject("B", NaN);
                var c:NameValueObject = new NameValueObject("C", NaN);
                var d:NameValueObject = new NameValueObject("D", NaN);

                ac.addItem(one);
                ac.addItem(two);
                ac.addItem(three);
                ac.addItem(four);
                ac.addItem(b);
                ac.addItem(a);
                ac.addItem(d);
                ac.addItem(c);              
            }

            private function numericValueSort(obj1:Object, obj2:Object):int
            {
                var value1:Number = (obj1 as NameValueObject).value;
                var value2:Number = (obj2 as NameValueObject).value;

                return ObjectUtil.numericCompare(value1, value2);
            }

            private function codeLabelFunction(item:Object, column:AdvancedDataGridColumn):String
            {
                return (item as NameValueObject).code;
            }

        ]]>
    </mx:Script>

    <mx:AdvancedDataGrid width="500" height="300" dataProvider="{ac}">
        <mx:columns>
            <mx:AdvancedDataGridColumn id="codeColumn" 
                                       headerText="Code"
                                       dataField="value"
                                       labelFunction="codeLabelFunction"
                                       sortCompareFunction="numericValueSort">

            </mx:AdvancedDataGridColumn>
            <mx:AdvancedDataGridColumn id="numericValueColumn" 
                                       headerText="Value"
                                       dataField="value"
                                       sortCompareFunction="numericValueSort">

            </mx:AdvancedDataGridColumn>
        </mx:columns>
    </mx:AdvancedDataGrid>
</mx:Application>

NaveValueObject 类

package
{
    public class NameValueObject
    {
        public var code:String;
        public var value:Number;

        public function NameValueObject(aCode:String, aNumber:Number)
        {
            code = aCode;
            value = aNumber;
        }
    }
}
4

4 回答 4

1

试试这个:

private function numericValueSort(obj1:Object, obj2:Object):int
{
    var o1:NameValueObject = obj1 as NameValueObject;
    var o2:NameValueObject = obj2 as NameValueObject;

    var ret:int = 0;
    if (isNaN(o1.value) || isNaN(o2.value)) {
        if (o1.code > o2.code) {
            ret = 1;
        } else if (o1.code < o2.code){
            ret = -1;
        }
    } else {
        ret = ObjectUtil.numericCompare(o1.value, o2.value);
    }
    return ret;
}

您的函数进程号要么被重视,要么在两个对象的代码字段之间进行比较

于 2013-08-26T15:12:43.640 回答
0

以下比较函数将优先考虑数值并根据代码对 NaN 值进行排序。方法是为每个对象组成一个新字符串,并在字符串前面加上一个表示优先级(A > B)的值:

private function numericValueSort(obj1:NameValueObject, obj2:NameValueObject):int {
  var a:String = (isNaN(obj1.value) ? "B" : "A") + obj1.value + obj1.code;
  var b:String = (isNaN(obj2.value) ? "B" : "A") + obj2.value + obj2.code;
  return ObjectUtil.stringCompare(a, b);
}

请注意,例如,在对 1、2、11 进行排序时,这可能会产生奇怪的结果。在这种情况下,您最好使用自然 compare。AS3Commons Lang 库中有一个可用的 ActionScript 实现。

于 2013-08-26T20:14:04.970 回答
0

我想通了,这是我最终使用的 sortCompareFunction:

它检查值无效的 3 个可能条件。如果唯一的是 NaN,则返回 1 或 -1,否则根据代码列进行排序。

然后,如果两个值都有效(不是 NaN),则进行常规比较:

private function numericValueSort(obj1:Object, obj2:Object):int
{
    var o1:NameValueObject = obj1 as NameValueObject;
    var o2:NameValueObject = obj2 as NameValueObject;

    if( isNaN(o1.value) && !isNaN(o2.value) ){
        return 1; // o1 appears after o2;
    }
    if( !isNaN(o1.value) && isNaN(o2.value) ){
        return -1; // o1 appears before o2
    }
    if( isNaN(o1.value) && isNaN(o2.value) ){
            // Both values are NaN, so they will have been placed 
            // at the end when compared with valid values (from previous two 
            // IF statements, but now to compare to each other, we sort using the 
            // code field
        return ObjectUtil.stringCompare(o1.code, o2.code);
    }
    // If neither value is NaN, then do a regular numeric compare
    return ObjectUtil.numericCompare(o1.value, o2.value);
}

在此处输入图像描述

于 2013-08-27T09:17:05.443 回答
0

无论排序如何,我都希望所有 NaN 值都位于底部。除了 Nan 值之外,是否应该对其进行排序(将所有 NaN 值保留在底部)?

于 2015-02-13T05:48:24.280 回答