【JavaScript】forEachメソッドの書き方と使い方の基本
JavaScriptの繰り返し処理で使うforEachメソッドの基本を解説します。配列の各要素を順番に処理する書き方をはじめ、オブジェクトでの応用的な使い方、continue/breakの代替方法など、実践的なテクニックをサンプルコード付きで学ぶことができます。
開発環境
- OS: Windows10
- Editor: Visual Studio Code
- JavaScript: ES6以降
JavaScriptのforEachメソッドとは
forEachメソッドは、配列のように複数のデータが入ったまとまり(データ構造)に対して、その中身を一つずつ順番に取り出して、あらかじめ決められた処理を実行するための機能です。繰り返し処理をよりシンプルに記述する際によく使われます。
forEachメソッドを使用する際には、「各要素に対して具体的にどのような処理を行うか」を定義した関数(コールバック関数)を渡します。forEachメソッドは、各要素の処理を行うたびに、このコールバック関数へ自動的に情報を引数として渡します。
渡される引数の内容は、元となるデータの種類(配列、Map、Set)によって以下のように異なります。
| データ構造 | 第1引数 | 第2引数 | 第3引数 | 補足 |
|---|---|---|---|---|
| 配列 | 要素の値 | インデックス | 元の配列 | |
| Map | 要素の値 | キー | 元の Map | |
| Set | 要素の値 | 要素の値** | 元の Set | Mapと形式を合わせるため、第2引数も値になる |
-
配列の場合 最も基本的な使い方です。第1引数には要素の値、第2引数にはその要素が配列の何番目にあるかを示す位置番号(インデックス)が渡されます。
-
Mapの場合 Mapは「キー」と「値」をペアで管理するデータ構造です。そのため、第1引数には「値」、第2引数にはその値とペアになっている「キー」が渡されます。
-
Setの場合 Setは重複しない値のみを格納するデータ構造で、キーという概念がありません。しかし、Mapなど他のデータ構造と使い方を合わせるため、第1引数と第2引数の両方に同じ「要素の値」が渡されるという少し特殊な仕様になっています。
どのデータ構造であっても、第3引数にはforEachメソッドを呼び出した元のデータ全体(配列、Map、Setそのもの)が渡されます。
forEach メソッドの書き方
forEach メソッドは、配列やMap、Setのようなコレクションに含まれる各要素に対して、順番に同じ処理を繰り返し実行するための機能です。このメソッドを使うことで、ループ処理を簡潔に記述できます。
配列の場合
配列で forEach を使うと、配列に含まれる要素を先頭から一つずつ取り出して、指定した処理を実行できます。
1配列.forEach(function(値, インデックス, 元の配列) { 2 // 値やインデックスを使った処理 3});
forEach の括弧の中に記述する関数は、最大で3つの情報を受け取ることができます。これらを引数(ひきすう)と呼びます。
- 値: 現在処理の対象となっている配列の要素そのものです。
- インデックス: 現在処理している要素が、配列の何番目に位置するかを示す番号です。インデックスは0から始まります。
- 元の配列:
forEachメソッドを呼び出している配列全体を指します。
これらの引数は、必要に応じて省略できます。例えば、値だけが必要な場合は function(値) のように記述します。
Map/Set の場合
Map や Set といったデータ構造でも forEach を使って、各要素に対する繰り返し処理を行えます。
1マップまたはセット.forEach(function(値, キーまたは値, 元のマップまたはセット) { 2 // 各要素ごとに実行される処理 3});
こちらも配列の場合と同様に関数は最大3つの引数を受け取りますが、Map と Set でそれぞれの引数が指す内容が少し異なります。
- Map の場合: 引数は
(値, キー, 元のマップ)の順になります。第一引数にキーに対応する「値」、第二引数に「キー」が入ります。 - Set の場合: 引数は
(値, 値, 元のセット)の順になります。Setにはキーが存在しないため、第一引数と第二引数の両方に同じ「値」が入ります。これはMapとの互換性のためにこのように設計されています。
第三引数は、どちらの場合も forEach を呼び出した元の Map または Set そのものを指します。
サンプルコード
この記事では、JavaScriptの配列を操作する際に非常に便利なforEachメソッドについて、様々な使い方をサンプルコードと共に解説します。
javascript/chapter15/index.html
このHTMLファイルは、これから解説するJavaScriptファイル(script01.jsからscript09.jsまで)を読み込むための土台です。ブラウザでこのファイルを開くと、各JavaScriptファイルに書かれた処理が順番に実行され、その結果を開発者ツール(コンソール)で確認できます。
1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>JavaScriptチュートリアル</title> 7 </head> 8 9 <body> 10 <h1>JavaScriptチュートリアル</h1> 11 <script src="./script01.js" defer></script> 12 <script src="./script02.js" defer></script> 13 <script src="./script03.js" defer></script> 14 <script src="./script04.js" defer></script> 15 <script src="./script05.js" defer></script> 16 <script src="./script06.js" defer></script> 17 <script src="./script07.js" defer></script> 18 <script src="./script08.js" defer></script> 19 <script src="./script09.js" defer></script> 20 </body> 21</html> 22
javascript/chapter15/script01.js
これはforEachメソッドの最も基本的な使い方です。配列arrayの要素を先頭から一つずつ取り出し、console.log()を使ってコンソールに出力します。forEachは、配列の各要素に対して同じ処理を繰り返したい場合に使用します。
1// 基本的なforEach文 2const array = ["apple", "banana", "cherry"]; 3array.forEach((value) => { 4 console.log(value); 5}); 6
javascript/chapter15/script02.js
forEachメソッドでは、要素の値(value)だけでなく、その要素が配列の何番目にあるかを示すインデックス番号(index)も同時に取得できます。このコードでは、インデックス番号と値を組み合わせて「0: apple」のように出力しています。
1// キーと値の両方を使用するforEach文 2array.forEach((value, index) => { 3 console.log(`${index}: ${value}`); 4}); 5
javascript/chapter15/script03.js
forEachは配列のためのメソッドですが、Object.entries()と組み合わせることで、オブジェクト(連想配列)の内容をループ処理できます。Object.entries(user)は、オブジェクトを[キー, 値]という形の配列に変換します。その変換後の配列に対してforEachを使い、各キーと値のペアを出力しています。
1// 連想配列をforEachでループする(Object.entries()を使う) 2const user = { 3 name: "Alice", 4 age: 25, 5}; 6 7Object.entries(user).forEach(([key, value]) => { 8 console.log(`User's ${key}: ${value}`); 9}); 10
javascript/chapter15/script04.js
このコードは、forEachを入れ子(ネスト)にして、複雑なデータ構造を扱う例です。外側のforEachで配列multiArrayから各personオブジェクトを取り出します。次に、内側のforEachで、先ほどと同様にObject.entries()を使い、各personオブジェクトのキーと値を取り出して出力しています。
1// 多次元配列をforEachでループする 2const multiArray = [ 3 { name: "Alice", age: 25 }, 4 { name: "Bob", age: 22 }, 5 { name: "Charlie", age: 30 }, 6]; 7 8multiArray.forEach((person) => { 9 Object.entries(person).forEach(([key, value]) => { 10 console.log(`${key}: ${value}`); 11 }); 12}); 13
javascript/chapter15/script05.js
forEachループの途中で、特定の要素の処理だけをスキップしたい場合があります。一般的なfor文で使われるcontinueはforEachでは使えません。その代わりに、forEachの処理ブロック内でreturnを使用すると、その回の処理だけが中断され、次の要素の処理に進みます。この例ではitemが'c'の場合に処理をスキップしています。
1// forEach文の中でのcontinue(returnでスキップ) 2const items = ["a", "b", "c", "d", "e"]; 3items.forEach((item) => { 4 if (item === "c") return; // 'c'をスキップ(continueの代わり) 5 console.log(item); 6}); 7
javascript/chapter15/script06.js
forEachループを完全に中断するためのbreak文は、forEachでは使用できません。ループを途中で止めたい場合は、someメソッドなどで代用できます。someメソッドは、処理ブロック内でtrueを返した時点でループを終了します。このコードでは、animalが'fish'になった時点でtrueを返し、ループを中断させています。
1// forEach文の中でのbreak(forEachではbreak不可のため一時的な回避) 2const animals = ["cat", "dog", "bird", "fish", "rabbit"]; 3animals.some((animal) => { 4 if (animal === "fish") return true; // break相当 5 console.log(animal); 6 return false; 7}); 8
javascript/chapter15/script07.js
配列の各要素に同じ計算を行い、新しい配列を作成する例です。ここではmapメソッドを使用しています。mapは、元の配列の各要素に処理を加えた結果を、新しい配列として返します。このコードでは、numbers配列の各要素を2倍にした新しい配列を作成し、元のnumbers変数に再代入しています。最後のforEachは、変更後の配列の内容を確認するために使っています。
1// 配列の要素を参照で変更する(mapなら新しい配列を作成する) 2let numbers = [1, 2, 3, 4, 5]; 3numbers = numbers.map((number) => number * 2); // 各要素を2倍にする 4 5numbers.forEach((number) => { 6 console.log(number); 7}); 8
javascript/chapter15/script08.js
forEachループの中でif文を使うことで、条件に合う要素だけを処理することができます。この例では、配列valuesの中から30より大きい値だけをコンソールに出力しています。
1// 配列の中で条件を満たす要素だけ処理する 2const values = [10, 20, 30, 40, 50]; 3values.forEach((value) => { 4 if (value > 30) { 5 console.log(`${value}は30より大きい`); 6 } 7}); 8
javascript/chapter15/script09.js
これはforEachを使った実践的な練習問題です。配列wordsに含まれる各文字列をforEachで取り出し、文字列を大文字に変換するtoUpperCase()メソッドを使って変換後、コンソールに出力しています。
1// 配列に含まれる文字列をすべて大文字に変換して表示する練習問題 2const words = ["apple", "banana", "cherry"]; 3 4words.forEach((word) => { 5 console.log(word.toUpperCase()); 6}); 7
おわりに
forEachメソッドを使うと、配列の各要素に対する繰り返し処理を、for文よりもシンプルで直感的に記述できます。各要素の値だけでなく、それが何番目かを示すインデックスも同時に取得できるため、様々な場面で活用できます。また、Object.entries()と組み合わせることでオブジェクトにも応用したり、returnを使って特定の要素の処理をスキップしたりすることも可能です。break文は使えませんが、someメソッドなどで代用できることを覚えておけば、より多くの状況に対応できるようになるでしょう。