WSH/JScriptで配列の便利メソッドライブラリの案・compact/include/uniqなどを追加


配列の要素にユニーク性を持たせるために,
include,uniq, compactなどのメソッドを追加した。

どんどん便利になってゆく。 ====

/*

	WSHやピュアJSの便利配列メソッド

	ver 0.3 compact, include, uniqを追加
	ver 0.2 mapとfilterをreduceで記述
*/


// 配列のイテレータ
Array.prototype.each = function( func ){
	for( var i = 0; i < this.length; i ++ ){
		func.call( this, this[i], i ); 
	}
	return this; // チェインを継続
};


// Rubyのinjectに相当するメソッド
// http://d.hatena.ne.jp/TipsMemo+computer-technology/20150110/p1
Array.prototype.reduce = function( func, init_value ){
	// 初期値をセット
	var result = init_value;
	
	// 各要素ごとに
	this.each(function( item, index ){
		// 結果を累積更新する
		result = func( result, item, index );
	});
	
	// 累積結果を返す
	return result;
};


// オブジェクトを配列に変換
Array.src = function( iterable, func_item, func_length ){
	var arr = [];
	
	var length = null;
	if( func_length ){
		length = func_length( iterable );
	}else{
		iterable.length;
	}
	
	for( var i = 0; i < length; i ++ ){
		if( func_item ){
			arr.push( func_item( iterable, i ) );
		}else{
			arr.push( iterable[ i ] );
		}
	}
	return arr;
};


// -------------- 内部でreduceを使った処理 ---------------


// map
Array.prototype.map = function( func ){
	return this.reduce(function( result, item, index ){
		result.push( func.apply( result, [ item, index ] ) );
		return result;
	}, []);
};


// 多次元配列を1次元にならす関数。
// 内部でreduceを使用
Array.prototype.flatten = function(){
	return this.reduce(
		function( result, item ){
			return (
				//Array.isArray( item ) // WSHや古いIEでは動かない
				( item instanceof Array )
					// 対象要素が配列ならば,再帰する
					? result.concat( item.flatten() ) 

					// 対象要素が配列でなければ,要素として採用
					: result.concat( item )
			);
		},

		// 空配列からはじめる
		[]
	);
};


// 条件に合うものだけ残す
Array.prototype.filter = function( func ){
	return this.reduce(
		function( result, item ){
			if( func( item ) ){
				result.push( item );
			}
			
			return result;
		},
		[]
	);
};


// 要素がnullだったり空だったりfalseだったりするものを除去
Array.prototype.compact = function(){
	return this.filter(function(item){
		return (
			( !! item )
			&&
			( ( "" + item ).length > 0 )
		);
	})
};


// 含むか
Array.prototype.include = function(target_item){
	return this.reduce(function( result, item ){
		if( item == target_item ){
			result = true;
		}
		return result;
	}, false);
};


// 重複をなくす
Array.prototype.uniq = function(){
	return this.reduce(function( result, item ){
		if( ! result.include( item ) ){
			result.push( item );
		}
		return result;
	}, []);
};



// TODO: 配列データを手軽にダンプして中身を確認したい

// TODO: Haskellなどの便利メソッドの移植

// TODO: 重いループの非同期処理をするライブラリとマージ

// TODO: 二次元配列や動的計画法などのアルゴリズムをサポート