作成日:2025/5/21,最終更新日:2025/5/26

JavaScript / TypeScriptの繰り返し処理について

繰り返し処理に関する解説 : 実践編

この記事では、繰り返し処理とは何かについて詳しく解説します。


8. 配列の繰り返し処理(応用編:map / filter / reduce / some / every / find)

>>基礎編はこちら<<

解説: JavaScript では、配列を処理するための便利なメソッドがいくつも用意されています。
代表的なものが「map」「filter」「reduce」などの高階関数たち。
これらをマスターすると、for文を書かずにスマートなコードが書けるようになります。


この章では、それぞれの意味・使いどころ・違いを、具体例とともに解説します。




● map:配列の各要素を「変換」したいとき

// 例:価格の配列を税込価格に変換する
const prices = [100, 200, 300];
const withTax = prices.map(p => p * 1.1);
console.log(withTax);
// 結果 : [110, 220, 330]

「元の配列と同じ数だけ要素を持つ、新しい配列を作りたい」ときに使います。


● filter:条件に合う要素だけ「抽出」したいとき

// 例:300円以上の商品だけ取り出す
const prices = [100, 200, 300, 400];
const expensive = prices.filter(p => p >= 300);
console.log(expensive);
// 結果 : [300, 400]

「必要なものだけ残す」処理にぴったりです。


● reduce:配列を「集計」したいとき

// 例:合計金額を求める
const prices = [100, 200, 300];
const total = prices.reduce((acc, p) => acc + p, 0);
console.log(total);
// 結果 : 600

「ひとつの値にまとめたい」ときに使います。
1つ目の引数「acc」はこれまでの合計、2つ目の「p」は現在の要素を表します。


● some:ひとつでも条件を満たす要素があるか?

// 例:100円未満の商品があるか?
const prices = [120, 80, 300];
const hasCheap = prices.some(p => p < 100);
console.log(hasCheap);
// 結果 : true

「1つでもあれば true」というチェックに使えます。


● every:すべてが条件を満たすか?

// 例:すべての商品が100円以上か?
const prices = [120, 180, 300];
const allExpensive = prices.every(p => p >= 100);
console.log(allExpensive);
// 結果 : true

「全部そうなら true」 という条件チェックに便利です。


● find:最初に条件を満たす要素を1つだけ取得

// 例:100円未満の最初の商品を探す
const prices = [120, 80, 300];
const firstCheap = prices.find(p => p < 100);
console.log(firstCheap);
// 結果 : 80

見つかった最初の要素を返し、条件に合う要素がなければ undefined を返します。




💡 まとめ:6つの高階関数の違い

メソッド用途返り値
map変換要素数そのままの配列
filter絞り込み条件を満たす配列
reduce集計単一の値
some1つでも条件に合えば truetrue / false
everyすべて条件に合えば truetrue / false
find最初の1件要素 or undefined

これらを使いこなせると、「読みやすい」「バグりにくい」コードにぐっと近づきます。
次は、これらの書き方を「どう選ぶか?」という判断のコツを紹介していきます!


9. ループ文の選択基準:どう書くのがベスト?

解説: JavaScript では「for」「for...of」「forEach」「map」など、同じことを別の書き方で実現できる場面が多くあります。
でも、だからこそ「どれを選ぶべきか」に迷いやすいのも事実です。
この章では、それぞれの文法がどんな目的に向いているかどう選べばいいかを整理してお伝えします。




● for文:万能だけど、やや冗長

柔軟で何でもできる一方、ややコード量が増えます。
ループのインデックスやカウンタが必要なときに最適。

// 例:3つおきに表示したいなど、細かい制御が必要なとき
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for (let i = 0; i < array.length; i += 3) {
  console.log(array[i]); // 結果 : 0, 3, 6, 9
}

インデックスが必要な処理にはやっぱり「for」が頼りになります。


● forEach:値を使って「何かをする処理」に最適

配列の中身を順に処理するのに便利です。
配列の各要素を使って、何かの処理を実行したいときに使います。
たとえば「画面に表示する」「ログを出す」「関数を呼ぶ」など、結果を返すのではなく、見える動作を起こす処理に向いています。

// 例:画面に項目を表示する
items.forEach(item => {
  renderItem(item); // HTMLに描画
});

配列を変換する目的ではなく、「処理を実行する」目的なら forEach がシンプル。


● map:変換した結果を配列として残したいとき

変換して新しい配列を作るなら map 一択。
逆に、変換結果を使わないのに map を使うのは NG。

// ❌ これは map を使うべきではない例
items.map(item => {
  console.log(item);
});
// 結果は配列に使われていない → forEach が正解

// ✅ 正しい map の使い方
const doubled = items.map(item => item * 2);
console.log(doubled);

「その処理が map を使うべき理由があるか?」を考えることが大事です。




💡 判断のヒント:目的ベースで選ぼう

文法向いているケース補足
for インデックスが必要/制御が複雑 万能だが冗長になりやすい
forEach 値を使って何かを「実行」する処理 戻り値が必要ないならこれでOK
map 変換して配列として使いたい 使わない map は NG

「目的」と「結果をどう使うか?」を軸に考えれば、書き方で迷う時間がぐっと減ります。

次は、実際に「同じ処理を複数の書き方で比べてみる」ことで、違いを実感していきましょう!


10. for vs forEach vs map:書き換えで違いを体感

解説: これまでの章で、それぞれの書き方の特徴を学んできました。
今回は「同じ目的の処理」を for / forEach / map の3通りで書き比べて、実際にどんな違いがあるかを見てみましょう。


今回のお題は、「名前の配列をもとに、1人ずつ敬称『さん』をつけて表示または返す」処理です。




● for文で書く場合(手続き的に書く)

const names = ['田中', '佐藤', '鈴木'];
const result = [];

for (let i = 0; i < names.length; i++) {
  const withSuffix = names[i] + 'さん';
  result.push(withSuffix);
}
console.log(result);
// 結果 : ['田中さん', '佐藤さん', '鈴木さん']

わかりやすく柔軟ですが、処理が少し長めになりがちです。


● forEachで書く場合(1つずつ処理)

const names = ['田中', '佐藤', '鈴木'];
const result = [];

names.forEach(name => {
  result.push(name + 'さん');
});
console.log(result);
// 結果 : ['田中さん', '佐藤さん', '鈴木さん']

書き方はすっきり。返り値はないので、「実行が目的」という意図が明確です。


● mapで書く場合(変換が目的)

const names = ['田中', '佐藤', '鈴木'];

const result = names.map(name => name + 'さん');
console.log(result);
// 結果 : ['田中さん', '佐藤さん', '鈴木さん']

処理内容と意図(配列変換)が1行で表現されており、読みやすさ・意図の明確さともに優れています。 同じような処理でも、mapを使えば「何のための処理か」がひと目でわかるのが魅力です。




💡 書き換え体感まとめ

書き方特徴向いている場面
(どう使い分ける?)
for 自由度が高く、細かい制御が可能 条件付き、途中 break、インデックス使用など
forEach 順に処理を実行するだけならシンプル 表示処理や副作用を目的とする場合
※副作用:console.log や DOM操作など、値を返すのではなく「外部に影響を与える処理」
map 要素を変換して新しい配列を返す 変換結果を配列として使いたい場合

処理の「見た目」だけでなく、「目的(何のための処理か)」によって選ぶべき構文が変わることを体感できたでしょうか?
書き方に迷ったら、「**結果を使うのか、処理するだけか**」を考えるのがポイントです。

次は「**for...in を配列に使うとどうなるのか?**」という、よくある落とし穴を解説します!


11. 「for...in を配列に使ってはいけない」って本当?

解説: JavaScript には、オブジェクトのループに使う for...in と、配列のループに使う for...offorEach などがあります。 しかし初心者の方がやりがちなのが、「for...in を配列に使ってしまう」というミスです。


結論から言うと、配列には for...in は基本的に使わない方が安全です。
その理由を順に見ていきましょう。




● そもそも for...in って何?

for...in は、オブジェクトの「プロパティ名(キー)」を1つずつ取り出す構文です。

// オブジェクトに使うのが正しい使い方
const user = { name: "太郎", age: 25 };

for (const key in user) {
  console.log(key);         // 結果 : name, age
  console.log(user[key]);   // 結果 : 太郎, 25
}

● 配列に使うとどうなる?

配列にも「キー(インデックス番号)」があるので、一見 for...in が動くように見えます

// 一見ちゃんと動くように見える
const fruits = ["りんご", "みかん", "バナナ"];

for (const i in fruits) {
  console.log(i, fruits[i]); // 結果 : 0 りんご, 1 みかん, 2 バナナ
}

ですが、この使い方には落とし穴があります。


● for...in を配列に使ってはいけない理由

  • 順番が保証されない:キーの列挙順が、配列のインデックス順と異なることがある
  • 余計なプロパティも拾う:配列に後から追加されたメソッドやプロパティも含まれてしまう
  • 配列っぽく見えるだけで、挙動がオブジェクトと同じ
// 配列に余計なプロパティをつけると...
const fruits = ["りんご", "みかん", "バナナ"];
fruits.custom = "オマケ";

for (const i in fruits) {
  console.log(i, fruits[i]);
}
// 結果 : 0 りんご, 1 みかん, 2 バナナ, custom オマケ ← これが問題

このように、意図しないプロパティまで処理してしまう可能性があるため、配列には使うべきではないとされています。




💡 正しい使い方:配列には for / for...of / forEach を

  • for:インデックスが必要・細かい制御をしたいとき
  • for...of:配列の「中身」だけ順番に処理したいとき
  • forEach:見た目すっきり。副作用を目的とする処理に

「for...in はオブジェクト用、配列には使わない」
迷ったら for...of を基本に考えよう。

次は「配列処理のスピードが気になる人向けに、実行速度の傾向」について紹介します。


12. [補足] 実行速度・パフォーマンス比較

解説: 「結局、一番速いのはどれなの?」と気になる方も多いかもしれません。
ここでは for / forEach / map / for...of など、よく使う繰り返し構文の実行速度の傾向についてざっくり整理しておきます。


ただし!以下の点にご注意ください:

  • ✅ 環境(ブラウザ・CPU)によって結果は変わる
  • ✅ 配列の大きさや処理内容によっても大きく変わる
  • ✅ 実務では「可読性」や「意図の明確さ」のほうが重要



● ざっくりした実行速度の傾向

構文速度(目安)コメント
for ◎(最速クラス) 無駄が少なく、JSエンジンが最適化しやすい
for...of やや遅くなるが、コードがすっきり
forEach 関数コールのオーバーヘッドあり(やや重)
map / filter / reduce △〜◯ 関数型なので見た目はきれいだが、速度は控えめ

💡 ポイント:「速さ」より「意図のわかりやすさ」

実務では、1秒間に100万回回すような処理でなければ、速度差は誤差の範囲です。
それよりも大事なのは、意図が伝わる書き方をすることです。

たとえば、「変換したい」なら map、「処理を実行したい」なら forEach、インデックスが必要なら for ——
こうした目的と構文の対応関係が明確であるほうが、あとから読む人にとって理解しやすくなります。




✅ おまけ:実行時間を計測してみる

ブラウザの開発者ツールなどで console.time を使えば、処理速度を計測することも可能です。

const array = Array(100000).fill(1);

// for
console.time('for');
for (let i = 0; i < array.length; i++) {
  const x = array[i] * 2;
}
console.timeEnd('for');

// forEach
console.time('forEach');
array.forEach(val => {
  const x = val * 2;
});
console.timeEnd('forEach');

※ 実行時の数値は端末やブラウザにより異なります。


速度を求める場面ではこうした手法でベンチマークを取りつつ、基本は読みやすさ重視で選びましょう!

これで「配列操作と選び方のコツ」パートは終了です。次は「現場でも活きるループ応用編」に進んでいきましょう!