非標準。使用しないでください!
配列内包は非標準であり、Firefox 58 から削除されています。将来向きの用途には、Array.prototype.mapArray.prototype.filterアロー関数スプレッド構文 の使用を検討してください。

array comprehension 構文は、既存のものに基づいている新しい配列をすばやく組み立てることができるJavaScriptの式でした。しかし、これは標準仕様や Firefox の実装から削除されました。使用しないでください!

構文

[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 イテレーションは、ステートメントが許可されている場合。

配列内包は以前、ECMAScript 2016 で標準化を提案されていました。これは別のものに基づいて新たな配列を構成するための手っ取り早い方法を提供します。配列内包は一般に、map() および filter() を呼び出す代わりとして、あるいはそれら 2 つを結合する手段として用いることができます。

次の配列内包は数値の配列を取り込んで、その各数値を 2 倍した値による新しい配列を作成します。

var numbers = [1, 2, 3, 4];
var doubled = [for (i of numbers) i * 2];
console.log(doubled); // logs 2,4,6,8

これは以下の map() による操作と同等です:

var doubled = numbers.map(i => i * 2);

配列内包は、特定の式にマッチするアイテムの選択に用いることもできます。以下は、偶数だけを選択する内包です:

var numbers = [1, 2, 3, 21, 22, 30];
var evens = [for (i of numbers) if (i % 2 === 0) i];
console.log(evens); // logs 2,22,30

同じ目的で filter() を用いることができます:

var evens = numbers.filter(i => i % 2 === 0);

map() および filter() 方式の操作を、ひとつの配列内包に統合することができます。以下は偶数だけをフィルタリングして、それらを 2 倍した値を含む配列を作成します:

var numbers = [1, 2, 3, 21, 22, 30];
var doubledEvens = [for (i of numbers) if (i % 2 === 0) i * 2];
console.log(doubledEvens); // logs 4,44,60

配列内包の角括弧は、スコープ目的の暗黙的なブロックをもたらします。新しい変数 (上記の例における i ) は、let を用いて宣言されたかのように扱われます。つまり、それらの変数は配列内包の外部で使用できません。

配列内包の入力自体は、配列である必要はありません。イテレータおよびジェネレータ も使用できます。

文字列を入力とすることもできます。(配列状のオブジェクトにおいて) 前出の filter や map の動作を実現するには以下のようにします:

var str = 'abcdef';
var consonantsOnlyStr = [for (c of str) if (!(/[aeiouAEIOU]/).test(c)) c].join(''); // 'bcdf'
var interpolatedZeros = [for (c of str) c + '0' ].join(''); // 'a0b0c0d0e0f0'

繰り返しになりますが入力データの形式は維持されませんので、文字列へ戻すために join() を使用しなければなりません。

簡単な配列の内包表記

[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 2015 のドラフトでしたが、リビジョン 27 (2014 年 8 月) で取り除かれました。仕様セマンティクスのために ES2015 の古いリビジョンを参照してください。

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOS 版 SafariSamsung InternetNode.js
基本対応
非推奨非標準
Chrome 未対応 なしEdge 未対応 なしFirefox 未対応 30 — 58IE 未対応 なしOpera 未対応 なしSafari 未対応 なしWebView Android 未対応 なしChrome Android 未対応 なしEdge Mobile 未対応 なしFirefox Android 未対応 30 — 58Opera Android 未対応 なしSafari iOS 未対応 なしSamsung Internet Android 未対応 なしnodejs 未対応 なし

凡例

未対応  
未対応
非標準。ブラウザー間の互換性が低い可能性があります。
非標準。ブラウザー間の互換性が低い可能性があります。
非推奨。新しいウェブサイトでは使用しないでください。
非推奨。新しいウェブサイトでは使用しないでください。

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

JS1.7/JS1.8 の内包表記は、バージョン 46 で Gecko から削除しました (バグ 1220564)。

古い内包表記の構文 (使用しないでください!):

[X for (Y in Z)]
[X for each (Y in Z)]
[X for (Y of Z)]

違い:

  • ESNext の内包表記は全体の内包表記のかわりに"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.
  • ESNext の内包表記は代入式のかわりに"for"で始まります。
    • 旧: [i * 2 for (i of numbers)]
    • 新: [for (i of numbers) i * 2]
  • ESNext の内包表記は複数のifforコンポーネントを持ち得ます。
  • ESNext の内包表記はfor...ofでのみ動作し、for...inイテレーションで 動作しません。

コード更新の提案について、Bug 1220564 のコメント 42 をご覧ください。

関連情報

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

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