Apply MapReduce

by pasodania
♥0 | Line 96 | Modified 2009-09-03 18:07:48 | MIT License
play

ActionScript3 source code

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

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    
    public class Main extends Sprite{
        public var output:TextField;
        
        public function Main() {
            // write as3 code here..
            output = new TextField();
            var app:MapReduceCharCounter = new MapReduceCharCounter();
            app.count("gazacabbcb");
            output.appendText(app.getCharCount("b").toString());
            
            addChild(output);
        }
    }
}

class MapReduceCharCounter{
    public static var charCount:Object;
    
    public static function emit(input:ReduceInput, count:int):void{
        // その要素が何個あるかを設定する
        charCount[input.key] = count;
    }
    
    public function count(target:String):void{
    	var i:int;
        charCount = new Object();
        var map:MapTask = new MapTask();
        // MapTaskに渡してMapEntryリストを生成してもらう
        map.execute(target);
        map.melist.sortOn("key");	// MapEntryのリストをソート
        var rt:ReduceTask = new ReduceTask();
        // ソートしたMapEntryリストをReduceに与えて、重複無しのデータを取得する
        var inputList:Array = ReduceInputListFactory.createInstance(map.melist);
        for( i = 0; i< inputList.length; i++){
            rt.execute(inputList[i]);
        }
    }
    
    public function getCharCount(c:String):int{
        var index:String = c;
        return int(charCount[index]);
    }   
}

class MapTask{
    public var melist:Array = new Array();
    
    public function MapTask(){}
    // 一文字ずつMapEntryとしてリストに格納する
    public function execute(target:String):void{
        var len:int = target.length;
        for( var i:int = 0; i < len ; i++ ){
           var tmpME:MapEntry = new MapEntry(target.charAt(i) , 1);
           melist.push(tmpME);
        }
    }
}

class MapEntry{
    public var key:String;
    public var value:int;
    
    public function MapEntry(k:String, v:int){
        key = k;
        value = v;
    }
    
    public function equals(o:Object):Boolean{
        return (o != null) &&
                ( o is MapEntry) &&
                (MapEntry(o).key == key);
    }
    
    public function hasCode():String{
        return key;   
    }
}



class ReduceTask{
    public var count:int;

    public function ReduceTask(){}   
    
    public function execute(input:ReduceInput):void {
        count = 0;
        for(var i:int=0; i < input.list.length; i++){
            count++;
        }
        MapReduceCharCounter.emit(input, count);
    }
}

class ReduceInput {
    public var key:String;
    public var list:Array = new Array();
}

class ReduceInputListFactory {
    public static function createInstance(entryList:Array):Array{
        var instance:Array = new Array();
        var current:MapEntry = null;
        var ri:ReduceInput = null;
        
        // MapEntryリストをソート済みとして一つずつ回していく
        for( var i:int = 0; i < entryList.length; i++ ){
            var tmpME:MapEntry = MapEntry(entryList[i]);
            // currentと違うMapEntryであればcurrent更新する
            if(!tmpME.equals(current)){
                current = tmpME;
                ri = new ReduceInput();
                ri.key = tmpME.key;
                // 重複無しリストとして追加
                instance.push(ri);
            }
            // MapEntryカウント
            ri.list.push(tmpME);
        }
        return instance;
    }
}