JavaScript | 配列・オブジェクト:ループ処理 – for での配列処理

JavaScript JavaScript
スポンサーリンク

for とは何か

for は「カウンター(インデックス)を使って、配列を順番に処理する」ための基本的なループ構文です。ここが重要です:配列の長さと位置を明示的に扱えるので、部分処理・スキップ・早期終了・逆順など自由度が高い一方、インデックス管理のミスに注意が必要です。配列に特化した for…of/forEach と比べて、制御が細かくできるのが強みです。


基本構文と安全な書き方

昇順で全要素を処理する

const arr = [10, 20, 30];
for (let i = 0; i < arr.length; i++) {
  const value = arr[i];
  console.log(i, value);
}
JavaScript

ここが重要です:ループ条件は i < arr.length(“未満”)が鉄則。<= と誤記すると 1 回余分に回って undefined を読むバグになります。

ループ中に配列を変えない(基本)

// NG(長さが変わると i < arr.length の判定が変動して危険)
for (let i = 0; i < arr.length; i++) {
  arr.push(999); // 無限ループの原因に
}
JavaScript

ここが重要です:ループ対象の配列を破壊的に変更すると、境界が動きバグ源になります。必要なら“別配列へ結果を入れる”非破壊パターンにしてください。

事前に長さをキャッシュする(微最適化)

for (let i = 0, n = arr.length; i < n; i++) {
  // n を使うと毎回 length を読むコストを減らせる(特に古い環境や巨大配列で)
}
JavaScript

よく使うパターン(スキップ・早期終了・逆順)

条件でスキップ(continue)

for (let i = 0; i < arr.length; i++) {
  if (arr[i] == null) continue; // null/undefined を飛ばす
  // 有効要素だけ処理
}
JavaScript

ここが重要です:スキップは continue、処理中断は break。分岐を浅く保てるので読みやすくなります。

見つかったら終わる(break)

let foundIndex = -1;
for (let i = 0; i < arr.length; i++) {
  if (arr[i] === 42) { foundIndex = i; break; }
}
// foundIndex が -1 なら未発見
JavaScript

ここが重要です:for は“早期終了”が簡単。some や find でも書けますが、複合処理を同じループでしたいときは for が便利です。

逆順で処理する

for (let i = arr.length - 1; i >= 0; i--) {
  const value = arr[i];
  // 末尾から先頭へ
}
JavaScript

ここが重要です:末尾削除(pop)を伴う処理や、最新から過去へ走査する時に相性が良いです。


累積・変換・抽出(for で書く定番処理)

合計・平均

let sum = 0;
for (let i = 0; i < nums.length; i++) sum += nums[i];
const avg = nums.length ? sum / nums.length : 0;
JavaScript

新しい配列へ変換(map 相当)

const out = [];
for (let i = 0; i < users.length; i++) {
  const u = users[i];
  out.push({ ...u, active: true });
}
// users は変更しない(非破壊)
JavaScript

条件抽出(filter 相当)

const inStock = [];
for (let i = 0; i < products.length; i++) {
  const p = products[i];
  if (p.stock > 0) inStock.push(p);
}
JavaScript

検索と同時に加工(1パス最適化)

let hit = undefined;
const labels = [];
for (let i = 0; i < products.length; i++) {
  const p = products[i];
  if (p.stock > 0) labels.push(`${p.name} (${p.price})`);
  if (p.id === targetId && hit === undefined) hit = p; // 最初の一致
}
JavaScript

ここが重要です:複数目的を“1回の走査”でこなせるのが for の利点。性能と可読性のバランスを見て選びます。


インデックスの正しい扱い(深掘り)

範囲・境界の設計

  • 先頭から末尾へは i = 0 から i < arr.length。
  • 末尾から先頭へは i = arr.length – 1 から i >= 0。
  • 部分処理は開始・終了インデックスを明示(例:i = start; i < end)。

スライス的な処理を for で書く

const start = 2, end = 5; // [2,3,4] を処理(end は“開区間”)
for (let i = start; i < end && i < arr.length; i++) {
  // 部分処理
}
JavaScript

ここが重要です:“開区間”にすると off-by-one を避けやすい(end を含まないルール)。

ネスト配列・インデックスの組み合わせ

for (let i = 0; i < matrix.length; i++) {
  const row = matrix[i];
  for (let j = 0; j < row.length; j++) {
    const cell = row[j];
    // (i, j) の位置情報を使った処理
  }
}
JavaScript

ここが重要です:二重 for は座標処理に向く。外側・内側の境界を間違えないように“変数名”で意味を表現しましょう。


疎配列・undefined の挙動(注意点)

空スロットもインデックスは進む

const a = [];
a.length = 3; // [ <3 empty items> ]
for (let i = 0; i < a.length; i++) {
  console.log(i, a[i]); // 0 undefined, 1 undefined, 2 undefined
}
JavaScript

ここが重要です:for は“インデックス”で走るため、空スロットでも回ります。map/filter と違ってスキップされない点に注意し、必要なら事前に正規化(Array.from など)を行いましょう。

破壊的更新と組み合わせるときの順序

// 末尾削除しながら処理するなら逆順が安全
for (let i = arr.length - 1; i >= 0; i--) {
  if (shouldRemove(arr[i])) arr.splice(i, 1);
}
JavaScript

ここが重要です:前から削除するとインデックスが詰まって“取りこぼし”が起きます。削除は後ろからが鉄則。


for と他ループの使い分け(役割の違い)

for…of(値中心で簡潔)

for (const value of arr) {
  // 値だけ欲しい処理に最適(インデックス不要)
}
JavaScript

forEach(副作用を直書き)

arr.forEach((value, index) => { /* 返り値不要の副作用向け */ });
JavaScript

for(細かく制御)

  • インデックスが必要(位置・部分処理・逆順)
  • 早期終了(break)やスキップ(continue)を多用
  • 複数目的を1パスでやる最適化

ここが重要です:単純な「全件変換・抽出」は map/filter、柔軟な制御が必要なら for。目的に応じた道具を選ぶだけで、コードが読みやすく安定します。


実践例(UI・検証・アルゴリズム)

入力検証:最初の不正値を見つけて即終了

function validate(nums) {
  for (let i = 0; i < nums.length; i++) {
    const n = nums[i];
    if (!Number.isFinite(n) || n < 0) return { ok: false, index: i, value: n };
  }
  return { ok: true };
}
JavaScript

ページング:必要な範囲だけ取り出す

function page(arr, pageIndex, pageSize) {
  const start = pageIndex * pageSize;
  const end = Math.min(start + pageSize, arr.length);
  const out = [];
  for (let i = start; i < end; i++) out.push(arr[i]);
  return out;
}
JavaScript

2次元グリッド:周囲セルの合計

function sumNeighbors(grid, r, c) {
  let sum = 0;
  for (let i = r - 1; i <= r + 1; i++) {
    for (let j = c - 1; j <= c + 1; j++) {
      if (i === r && j === c) continue;
      if (grid[i]?.[j] != null) sum += grid[i][j];
    }
  }
  return sum;
}
JavaScript

まとめ

for は「インデックスを明示して配列を自在に制御する」ループです。境界は i < arr.length の“開区間”を守り、必要なら continue/break、逆順、部分処理を使い分ける。ループ対象を破壊的に変更しない、削除は後ろから、疎配列は回ってしまう点に注意。単純な変換・抽出は map/filter、細かな制御や複合処理の1パス最適化は for。これらを押さえれば、初心者でも読みやすく安全な配列ループを書けます。

タイトルとURLをコピーしました