Array comprehensions

この翻訳は不完全です。英語から この記事を翻訳 してください。

This is an experimental technology, part of the Harmony (ECMAScript 7) proposal.
Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.

array comprehension構文は、既存のものに基づいている新しい配列をすばやく組み立てることができるJavaScriptの式です。内包表記は、多くのプログラミング言語に存在し、 今度のECMAScript第7版標準では、JavaScriptの配列の内包表記を定義します。

ECMAScript第4版の提案に基づく、SpiderMonkeyでの古い配列の内包表記構文の違いについて下記をご覧ください。

構文

[for (x of iterable) x]
[for (x of iterable) if (condition) x]
[for (x of iterable) for (y of iterable) x + y]

説明

配列の内包表記内で、下記の二種類のコンポーネントが許されています。:

for-of イテレーションは常に最初のコンポーネントです。複数のfor-of イテレーションは、ステートメントが許可されている場合。

簡単な配列の内包表記

[for (i of [ 1, 2, 3 ]) i*i ]; 
// [ 1, 4, 9 ]

var abc = [ "A", "B", "C" ];
[for (letters of abc) letters.toLowerCase()];
// [ "a", "b", "c" ]

if文で配列の内包表記

var years = [ 1954, 1974, 1990, 2006, 2010, 2014 ];
[for (year of years) if (year > 2000) year];
// [ 2006, 2010, 2014 ]
[for (year of years) if (year > 2000) if(year < 2010) year];
// [ 2006], the same as below:
[for (year of years) if (year > 2000 && year < 2010) year];
// [ 2006] 

mapfilterを比較する配列の内包表記

配列の内包表記構文を理解する簡単な方法は、Array mapfilterメソッドと比較することです。:

var numbers = [ 1, 2, 3 ];

numbers.map(function (i) { return i * i });
numbers.map(i => i*i);
[for (i of numbers) i*i ];
// all are [ 1, 4, 9 ]

numbers.filter(function (i) { return i < 3 });
numbers.filter(i => i < 3);
[for (i of numbers) if (i < 3) i];
// all are [ 1, 2 ]

二つの配列の内包表記

二つの配列で動作させるために二つのfor-ofイテレーションを使用する:

var numbers = [ 1, 2, 3 ];
var letters = [ "a", "b", "c" ];

var cross = [for (i of numbers) for (j of letters) i+j];
// [ "1a", "1b", "1c", "2a", "2b", "2c", "3a", "3b", "3c" ]

var grid = [for (i of numbers) [for (j of letters) i+j]];
// [
//  ["1a", "1b", "1c"],
//  ["2a", "2b", "2c"],
//  ["3a", "3b", "3c"]
// ]

[for (i of numbers) if (i > 1) for (j of letters) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"], the same as below:

[for (i of numbers) for (j of letters) if (i > 1) if(j > "a") i+j]
// ["2b", "2c", "3b", "3c"]

[for (i of numbers) if (i > 1) [for (j of letters) if(j > "a") i+j]]
// [["2b", "2c"], ["3b", "3c"]], not the same as below:

[for (i of numbers) [for (j of letters) if (i > 1) if(j > "a") i+j]]
// [[], ["2b", "2c"], ["3b", "3c"]]

仕様

仕様 ステータス コメント
ECMAScript第7版のために提案中 まだ利用可能なドラフトはありません 最初はECMAScript第6版ドラフトでしたが、リビジョン27 (2014年8月)で取り除かれました。仕様セマンティクスのためにES6の古いリビジョンを参照してください。 更新されたバージョンは、新たなES7ドラフトに戻ってきます。

ブラウザ実装状況

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari
基本サポート 未サポート 30 (30) 未サポート 未サポート 未サポート
機能 Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本サポート 未サポート 未サポート 30.0 (30) 未サポート 未サポート 未サポート

SpiderMonkey固有の実装メモ

  • 識別子としてのletはサポートされていません。というのも、letは現在JSバージョン1.7とXULスクリプトタグにのみ使用できるからです。
  • 内包表記での構造化代入はまだサポートされていません(バグ 980828).

古いJS1.7/JS1.8の内包表記との違い

  • ES7の内包表記は全体の内包表記のかわりに"for"ノードごとに1スコープを生成します。
    • 旧: [()=>x for (x of [0, 1, 2])][1]() // 2
    • 新: [for (x of [0, 1, 2]) ()=>x][1]() // 1, each iteration creates a fresh binding for x.
  • ES7の内包表記は代入式のかわりに"for"で始まります。
    • 旧: [i * 2 for (i of numbers)]
    • 新: [for (i of numbers) i * 2]
  • ES7の内包表記は複数のifforコンポーネントを持ち得ます。
  • ES7の内包表記はfor...ofでのみ動作し、for...inイテレーションで 動作しません。

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: shide55
 最終更新者: shide55,