0

コード (文字列) と値 (数値) の 2 つの列を持つ AdvancedDatagrid があります。各列に同じソート関数を使用します。私がやりたいのは、Value 列 (数値データ) に基づいて両方の列を並べ替えることですが、利用可能な数字がない場合は、並べ替えを Code 列のアルファベット順に実行したいと考えています。

私がやろうとしていることを表す例で、直面している問題を単純化しました。

この図は 2 つの列を示しており、値列に基づいて両方の列が並べ替えられています。値が NaN の場合、Code 列の値をアルファベット順に並べ替えます。したがって、1、2、3、4 は同じままですが、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

0

並べ替えに関係なく、すべての NaN 値を一番下にしたい。Nan 値以外はソートする必要があります (すべての NaN 値を一番下に保持します)?

于 2015-02-13T05:48:24.280 に答える
0

私はそれを理解しました、そしてこれは私が最終的に使用したsortCompareFunctionです:

値が無効である可能性のある 3 つの条件をチェックします。1 つだけが 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 値を並べ替えます。アプローチは、オブジェクトごとに新しい文字列を作成し、文字列の前に優先度 (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 をソートすると、奇妙な結果になる可能性があることに注意してください。その場合、自然な比較を使用することをお勧めします。AS3Commons Lang ライブラリで利用可能な ActionScript 実装があります。

于 2013-08-26T20:14:04.970 に答える