JavaScript | 配列・オブジェクト:配列の基礎 – インデックスの概念

JavaScript JavaScript
スポンサーリンク

インデックスとは何か

インデックスは「配列の中で、要素に付いている番号」です。JavaScript では先頭が 0、次が 1…と続きます。ここが重要です:配列の要素数(length)とインデックスの最大値は「length − 1」。たとえば要素数 5 の配列の最後のインデックスは 4 です。範囲外(存在しないインデックス)を参照するとエラーではなく undefined が返ります。


0から始まる理由と基本アクセス

0始まりのアクセス例

const colors = ["red", "green", "blue"];
console.log(colors[0]); // "red"(先頭)
console.log(colors[1]); // "green"
console.log(colors[2]); // "blue"(最後)
console.log(colors[3]); // undefined(範囲外)
JavaScript

ここが重要です:先頭は 0。末尾の安全な参照は colors[colors.length – 1] を使います。length と組み合わせるのが定石です。

範囲チェックの考え方

function getAt(arr, i) {
  if (i < 0 || i >= arr.length) return undefined; // 範囲外
  return arr[i];
}
JavaScript

ここが重要です:インデックスは 0 以上 length 未満が有効範囲。送られてくる値が安全かどうか、最初に境界を確認するとバグが減ります。


負のインデックスに“見たい気持ち”を叶える at()

at() で末尾を直感的に参照

const a = [10, 20, 30, 40];
console.log(a.at(-1)); // 40(最後)
console.log(a.at(-2)); // 30(最後から2番目)
JavaScript

ここが重要です:a[a.length – 1] の代わりに a.at(-1) が使えます。負の値は「後ろから数える」。可読性が上がり、オフバイワン(±1のズレ)ミスを減らせます。


インデックスとループ(i を正しく扱う)

伝統的 for で i を使う

const arr = ["A", "B", "C"];
for (let i = 0; i < arr.length; i++) {
  console.log(i, arr[i]);
}
JavaScript

ここが重要です:位置(i)も値も必要な処理ではこの形が明快。arr.length は長さに従ってループを止める安全装置です。

for…of と entries() の合わせ技

for (const [i, v] of ["A","B","C"].entries()) {
  console.log(i, v); // 0,"A" → 1,"B" → 2,"C"
}
JavaScript

ここが重要です:entries() は「インデックスと値のペア」を返します。i と v を同時に使う処理で、読みやすく正確に書けます。


探索(どこにある?)と一致判定

indexOf と lastIndexOf(値の場所を探す)

const list = ["pen", "book", "pen"];
console.log(list.indexOf("pen"));      // 0(最初の位置)
console.log(list.lastIndexOf("pen"));  // 2(最後の位置)
console.log(list.indexOf("eraser"));   // -1(見つからない)
JavaScript

ここが重要です:見つからないときは -1。条件分岐では if (idx !== -1) のように判定します。先頭か最後かを使い分けると、意図通りの位置が取れます。

findIndex(条件で位置を探す)

const users = [{id:1},{id:2},{id:3}];
const idx = users.findIndex(u => u.id === 2); // 1
JavaScript

ここが重要です:単なる“値一致”ではなく“条件で探す”なら findIndex。見つからなければ -1 なので、その後の操作(挿入・削除)の分岐が簡単になります。


挿入・削除とインデックス(splice の正しい使い方)

任意位置に挿入・削除

const a = ["A","B","C","D"];

// 2番目の位置(インデックス1)から1件削除
a.splice(1, 1);            // → ["A","C","D"]

// 2番目の位置(インデックス1)へ挿入(削除0件)
a.splice(1, 0, "X");       // → ["A","X","C","D"]
JavaScript

ここが重要です:splice(開始位置, 削除数, 挿入する…値)。開始位置は“その位置の前に挿入・その位置から削除”の基準になります。実データの並びを壊さずに扱うにはインデックスの指定が肝心です。

“見つかった場所で操作する”安全パターン

const items = ["pen","book","note"];
const i = items.indexOf("book");
if (i !== -1) items.splice(i, 1); // "book" を削除
JavaScript

ここが重要です:探索 → 操作 の順序にすると、“存在しないものを削る”事故を防げます。-1 判定を忘れないこと。


“穴”と length の落とし穴(疎な配列に注意)

連続カンマは“穴”になる

const a = [1, , 3];        // 真ん中が“穴”
console.log(a.length);     // 3
a.forEach(v => console.log(v)); // 1 と 3 だけ(穴はスキップされがち)
JavaScript

ここが重要です:穴は undefined と違い、メソッドの挙動が不統一になりやすい問題児です。意図せず疎な配列を作らないこと。必要なら明示的に undefined を置くか、穴のない初期化を行います。

length を直接書き換える影響

const b = [10, 20, 30, 40];
b.length = 2;   // 末尾が切り落とされる → [10, 20]
JavaScript

ここが重要です:length を小さくすると末尾が消えます。配列を“縮める”効果があるため、意図せずデータを失わないよう注意してください。


よくあるバグの芽(オフバイワンと境界条件)

オフバイワン(±1ズレ)を防ぐ書き方

const arr = ["A","B","C"];
// 末尾の処理は at(-1) が安全
const last = arr.at(-1);

// ループは i < arr.length(<= ではない)
for (let i = 0; i < arr.length; i++) { /* ... */ }
JavaScript

ここが重要です:最後の要素への参照は at(-1)、ループの条件は i < length を徹底すると、境界のズレをほぼ根絶できます。

“存在しないインデックス”への代入は配列を伸ばす

const a = ["A","B"];
a[5] = "X"; // 長さが 6 になり、途中に穴ができる
JavaScript

ここが重要です:インデックスを飛ばして代入すると穴だらけの配列になります。push/splice(意図した位置)での追加を心がけてください。


まとめ

インデックスは「0から始まり length − 1 が最後」というルールがすべての基礎です。範囲外は undefined、探索は indexOf/lastIndexOf/findIndex を使い、操作は splice を“見つけた位置”に対して行うのが安全。末尾参照には at(-1)、ループ条件は i < length を徹底してオフバイワンを防ぎます。疎な配列(穴)と length の直接操作は思わぬ挙動を招くため避け、push/splice など“意図が明確な手段”で配列を扱う。これらを押さえれば、初心者でもインデックスを正確に使いこなせます。

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