Vector.sort() は元の並びを変更する

by yprops forked from テキスト表示用 (diff: 85)
♥0 | Line 74 | Modified 2010-12-09 16:47:03 | MIT License
play

ActionScript3 source code

/**
 * Copyright yprops ( http://wonderfl.net/user/yprops )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uz96
 */

// forked from yprops's DebugText
package {
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.text.TextField;
    public class DebugText extends Sprite {
        
        
        //-----------props-------------------
        
        private var vc0 :Vector.<Param>;
        private var vc1 :Vector.<Param>;
        private var vc2 :Vector.<Param>;
        
        //-----------init--------------------
        
        /**
         * Vector.sort() で評価する値が同じ場合の挙動
         */
        public function DebugText() {
            addDeb(400, 450);
            stage.frameRate = 10;
            
            vc0 = new Vector.<Param>(7, true);
            for(var i :uint = 0; i < vc0.length; i++) vc0[i] = new Param(i, i%2);
            vc1 = vc0.concat();
            vc2 = vc0.concat();
            
            addEventListener(Event.ENTER_FRAME, update);
            //stage.addEventListener(MouseEvent.CLICK, update);
            //update(null);
        }
        
        
        //------------main-------------------
        
        private function update(ev:Event) :void{
            var i :uint, p :Param;
            clearDeb();
            
            //--------
            addDebLine(
                "■例A:Vector.sort() は元の Vector の並びを変更する。"+
                "\nかつ、クイックソートの仕様により、同値の場合の並び順に癖がある。"+
                "\nそのため繰り返し sort() すると下記のようにブレる事がある。"
            );
            output( vc0.sort(simpleSort) );
            
            //--------
            addDebLine("\n■例B:毎回 concat() したものを sort() すればブレはなくなる。");
            output( vc1.concat().sort(simpleSort) );
            
            //--------
            addDebLine("\n■例C:または IDなど一意のパラメータを比較処理に組み込む。");
            output( vc2.sort(sortWithId) );
        }
        
        //単純ソート
        private function simpleSort(p0:Param, p1:Param):Number {
            return p0.num - p1.num;
        }
        //ID を加味したソート
        private function sortWithId(p0:Param, p1:Param):Number {
            var n :Number = p0.num - p1.num;
            return (n != 0)? n : (p0.id > p1.id)? 1 : -1;
        }
        
        //出力
        private function output(vc :Vector.<Param>) :void{
            for(var i :uint = 0; i < vc.length; i++){
                addDebLine("id:" + vc[i].id.toString() + "\tnum:" + vc[i].num );
            }
        }

        
        
        //-------------------------------
        
        private var deb :TextField;
        private function addDeb(w:uint, h:uint) :void{
                deb = new TextField();
                deb.wordWrap = true;
                deb.width = w;
                deb.height = h;
                deb.border = true;
                deb.borderColor = 0;
                deb.background = true;
                deb.backgroundColor = 0x99ffffff;
                deb.text = "beginDebugText-------\n";
                addChild(deb);
        }
        private function addDebLine(str :String) :void{
                deb.appendText(str + "\n");
                deb.scrollV = deb.maxScrollV;
        }
        private function clearDeb() :void{
            deb.text = "";
        }

    }
}


//------------param class---------------

internal class Param{
    internal var id :uint;
    internal var num :Number;
    public function Param(id :uint, num :Number) {
        this.id = id;
        this.num = num;
    }
}