読者です 読者をやめる 読者になる 読者になる
スポンサーリンク

JavaScriptの配列便利メソッドArray#reduceを,WSH/JScriptで使えるようにする方法 (flattenメソッドつき)

javascript WSH MS IE サンプルコード

いまやIEやFirefoxで標準的に利用可能な,配列の便利メソッドであるArray.prototype.reduceだが,

これをWSHでも使えるようにしたい。

firefoxのJavaScriptの便利関数,reduceの使い方とサンプルコード。配列の全要素を順番に使い,一つの値を生成。Rubyのinjectに相当
http://computer-technology.hateblo.jp/entry/20141221/p2

  • 「配列の全要素を順番に使い,1つの値を生み出す」というメソッド


reduce メソッド (Array) (JavaScript)
http://msdn.microsoft.com/ja-jp/libra...

  • Internet Explorer 9 標準、Internet Explorer 10 標準、Internet Explorer 11 標準の各ドキュメント モードでサポートされています。ストア アプリ (Windows 8 および Windows Phone 8.1) でもサポートされます。「バージョン情報」を参照してください。
  • Quirks、Internet Explorer 6 標準、Internet Explorer 7 標準、Internet Explorer 8 標準の各ドキュメント モードでサポートされていません。


WSHでreduceを使えるようにするためのコードは下記の通り。

// WSHだとArray.reduceが未定義なので自前で作る
if( ! Array.prototype.reduce ){

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

	// Rubyのinjectに相当するメソッド
	Array.prototype.reduce = function( func, init_value ){
		// 初期値をセット
		var result = init_value;
		
		// 各要素ごとに
		this.each(function( item ){
			// 結果を累積更新する
			result = func( result, item )
		});
		
		// 累積結果を返す
		return result;
	};
}


// WSHでのArray#reduceの使用例


var res = [1,2,3,4,5]
  .reduce(

    // 第一引数として,無名関数を渡す。
    function( result, item ){
      // 「結果」に対して「要素」を作用させ,結果を更新する。
      result *= item; 

      // 無名関数の中では,最後に「結果」を返す。
      return result; 
    }, 

    // 「結果」の初期値
    1 
  );

WScript.Echo( res ); // 120



// 多次元配列を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 )
	    	);
		},
		
		// 空配列からはじめる
		[]
	);
};


WScript.Echo(
	[ [ 0, 1 ], [ 2, [3], 4 ], [5, 6], [7, 8, 9] ]
		.flatten().join(",")
);
	// 0,1,2,3,4,5,6,7,8,9


flatten関数について:

JavaScript で flatten - Qiita
http://qiita.com/shuhei/items/5a3d3a7...

  • 配列の配列を展開します。


配列深くても全部フラットにするArray.flatten - ぷちてく - Petittech
http://ptech.g.hatena.ne.jp/noromanba...

  • 全部greedyにやる


多元配列を一元配列に変換 (JavaScript): Days on the Moon
http://nanto.asablo.jp/blog/2005/10/0...

  • 多元配列を一元配列に変換する

isArrayについて:

Array.isArray 関数 (JavaScript)
http://msdn.microsoft.com/ja-jp/libra...

  • Internet Explorer 9 標準、Internet Explorer 10 標準、Internet Explorer 11 標準の各ドキュメント モードでサポートされています。ストア アプリ (Windows 8 および Windows Phone 8.1) でもサポートされます。「バージョン情報」を参照してください。 Quirks、Internet Explorer 6 標準、Internet Explorer 7 標準、Internet Explorer 8 標準の各ドキュメント モードでサポートされていません。


javascript - How to detect if a variable is an array - Stack Overflow
http://stackoverflow.com/questions/10...

  • obj instanceof Array This won't work if the object is passed across frame boundaries as each frame has its own Array object. You can work around this by checking the internal Class property of the object. To get it, use Object.prototype.toString() (this is guaranteed to work by ECMA-262): Object.prototype.toString.call(obj) === '[object Array]'