1. インデックスとは?
インデックス(index)とは、データ構造の要素にアクセスするための「位置番号」のことです。
ITTIたとえば、先生が『出席番号順に答えて』と言うと、生徒が『1番!』『2番!』と順番に答えますよね。この番号がインデックスのイメージです。
この「順番に並んだ番号」が、まさにインデックスのイメージです。
JavaScriptでは主に以下の場面で登場します。
• 配列(Array):要素の順序を示す番号
• 文字列(String):文字の位置を示す番号
• オブジェクトやMap:キーをインデックス的に扱うケース
• ループ処理:forやforEachでインデックスを利用
などなど



インデックスがあるおかげで、1つの配列の中に複数のデータをまとめて管理できます。
もしインデックスがなければ、配列の中で、fruit1, fruit2, fruit3 のように変数をたくさん作る必要があり、コードが煩雑になります。
インデックスを使えば、fruits[0] や fruits[1] のように1つの配列から自由に要素を選べるため、コードをシンプルに保てるのです。



ということで、ここからはコード専門官のイティセルが解説します。イティセルさん!よろしくお願いします!



イティセルです。読者の皆さんにわかりやすくお伝えしていきますね!
2. 配列とインデックス


配列は最も典型的にインデックスを使うデータ構造です。
JavaScriptの配列は0から始まるインデックスを持ちます。



appleを選びたいから、0番を指定しよう
const fruits = ["apple", "banana", "cherry"];
console.log(fruits[0]);
実行結果
"apple"


cherryを選びたいから、2番を指定しよう
const fruits = ["apple", "banana", "cherry"];
console.log(fruits[2]);
実行結果
"cherry"2.1 インデックスを使った要素の更新



1番目にあるbananaからorangeに更新しよう
const fruits = ["apple", "banana", "cherry"];
fruits[1] = "orange";
console.log(fruits);
実行結果
["apple", "orange"(⇦更新してる!) , "cherry"]2.2 配列の長さとインデックス
array.lengthは要素数を返します。JavaScriptの配列はインデックスが 0から始まる ため、最後の要素を取得するには「要素数 – 1」を指定する必要があります。



例えば、次の配列には “apple”, “banana”, “cherry” の3つの要素があります。
要素数は3つなので、最後の要素を取り出すには 3 – 1 = 2、つまり2番を指定します。
const fruits = ["apple", "banana", "cherry"];
console.log(fruits[fruits.length - 1]);
実行結果
"cherry"3. 文字列とインデックス


文字列も配列のようにインデックスでアクセス可能です。



インデックスは 0から始まる ので、最初の文字は 0 を指定します。
const word = "JavaScript";
console.log(word[0]);
実行結果
"J"


文字列の最後の文字を取り出すには、length – 1 を指定します。
“JavaScript” は 10文字なので、10 – 1 = 9=9番目を指定すると “t” が取り出せます。
const word = "JavaScript";
console.log(word[word.length - 1]);
実行結果
"t"
ただし、文字列はイミュータブル(変更不可)なので、word[0] = “X” のような代入はできません。



イミュータブル(immutable)とは「変更できない」という意味です。
JavaScriptにおいて、文字列はイミュータブルなデータ型に分類されます。つまり、一度作られた文字列は、その中身を直接書き換えることができません。
例えば「JavaScript」という文字列があったとします。この文字列の先頭を「X」に変えて「XavaScript」にしようとしても、元の文字列を直接改造することはできません。文字列は常に固定されており、部分的に差し替えることは不可能なのです。
let word = "JavaScript";
word[0] = "X"; ⇦注目!!!!!JをXに変更しようとしてる
console.log(word);
実行結果
"JavaScript"(変わらない)


文字列を変更したい場合は、新しい文字列を作り直す必要があります。
let word = "JavaScript";
word = "X" + word.slice(1); →XとavaScriptを合わせよっていう命令に設定
console.log(word);
実行結果
"XavaScript"4. インデックス検索メソッド


4.1 `indexOf` と `lastIndexOf`
const colors = ["red", "blue", "green", "blue"];
console.log(colors.indexOf("blue"));
実行結果
1


最初に出てくる “blue” は 1番 にあったね
const colors = ["red", "blue", "green", "blue"];
console.log(colors.lastIndexOf("blue"));
実行結果
3


最後に出てくる “blue” は 3番 にあったね
4.2 `findIndex`



25より大きい数字は何番かな?
const numbers = [10, 20, 30, 40];
const index = numbers.findIndex(n => n > 25);
console.log(index);
実行結果
2


25より大きい数字は30で、結果は2番だね
5. ループとインデックス


5.1 `for`ループ



forを使ってループさせてみよう
const fruits = ["apple", "banana", "cherry"];
for (let i = 0; i < fruits.length; i++) {
console.log(i, fruits[i]);
}
実行結果
0 apple
1 banana
2 cherry


実行結果は 0 → 1 → 2 と順番に並んでいますね。
for ループは インデックスを一度ずつ進めていくだけで、0に戻って繰り返すわけではありません。
5.2 `forEach`



forEachを使ってループさせてみよう
const fruits = ["apple", "banana", "cherry"];
fruits.forEach((item, index) => {
console.log(index, item);
});
実行結果
0 apple
1 banana
2 cherry


forEach は配列の要素を順番に処理するメソッドです。
for のコードと比べると、シンプルで読みやすいのが特徴です。
ただし、forEach では break や continue が使えない点には注意しましょう。
6. オブジェクトとインデックス的アクセス


オブジェクトは数値インデックスを持ちませんが、キーをインデックス的に扱うことができます。



まず、キーは “name”, “age”, “city”とします。
Object.keys() を使えばキーを配列として取り出し、インデックス的に扱うことができます。
const user = { name: "Taro", age: 25, city: "Tokyo" };
const keys = Object.keys(user);
console.log(keys[0]);
実行結果
"name"


keys[0] は “name” です。つまり「最初のキー」を取り出していますね。



次、
console.log(user[keys[0]]); の中で書かれている user は「オブジェクトの名前」です。
keys[0] は “name” なので、user[keys[0]] は user[“name”] と同じ意味になります。
つまり「キー “name” に対応する値を取り出す」ということになり、実行結果は “Taro” です。
わかりやすくすると
• keys[0] は “name”
• user[“name”] → “Taro”
となり、結果は”Taro”になるわけです。
const user = { name: "Taro", age: 25, city: "Tokyo" };
const keys = Object.keys(user);
console.log(user[keys[0]]);
実行結果
"Taro"7. Map/Setとインデックス


MapやSetは順序を保持しますが、直接インデックスでアクセスはできません。(map.keys()[1] はエラー)
代わりにイテレーションで順序を利用します。
その前に 配列の map() メソッド について説明します!



map() とは、配列の全ての要素に処理をかけて、新しい配列を作るメソッドです。
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);
console.log(doubled);
実行結果
[2, 4, 6]


このコードでは、配列 [1, 2, 3] の 全ての要素に ×2 の処理をかけて、
新しい配列 [2, 4, 6] が返されています。
話に戻ります



map.keys() だけでは配列にはなりません。
スプレッド構文 … を使って […map.keys()] と書くことで、イテレーターを配列に変換できます。
その結果 [1] でアクセスでき、実行結果は “name” になります。
もし配列に変換しなければ、インデックスアクセスはできないためエラーになります。
const map = new Map([
["id", 1],
["name", "Hanako"],
["age", 30]
]);
console.log([...map.keys()][1]);
実行結果
"name"const map = new Map([
["id", 1],
["name", "Hanako"],
["age", 30]
]);
console.log(map.keys()[1]);
実行結果
エラー8. 実用例:検索フォームでのインデックス利用


例えば、検索結果リストから「最初に条件を満たす要素の位置」を取得するケース。



要するに、調べたいときに使えるコードです。
indexOf() メソッドを使ってみましょう。
このコードでは、target に “Smartphone” を設定し、配列 products の中から探しています。
products.indexOf(target) は配列の中から “Smartphone” を探し、最初に見つかった位置(インデックス番号)を返します。
const products = ["PC", "Tablet", "Smartphone", "Camera"];
const target = "Smartphone";
const index = products.indexOf(target);


indexOf() は見つからなければ -1 を返す仕様なので、index !== -1 で「見つかったかどうか」を判定しています。
if (index !== -1) {
console.log(`${target} は ${index} 番目にあります`);
}


この例では “Smartphone” が2番目にあるため、実行結果は “Smartphone は 2 番目にあります” と表示されます。
見つからなければ -1 になります。
実行結果
Smartphone は 2 番目にあります9. 配列操作メソッド


9.1. `push` / `pop` / `shift` / `unshift`



push は配列の末尾に要素を追加します。
例: [1, 2, 3] に 4 を追加すると → [1, 2, 3, 4]
let arr = [1, 2, 3];
arr.push(4);
実行結果
[1, 2, 3, 4]


pop は配列の末尾の要素を削除します。
例: [1, 2, 3, 4] から末尾を削除すると → [1, 2, 3]
let arr = [1, 2, 3, 4];
arr.pop();
実行結果
[1, 2, 3]


shift は配列の先頭の要素を削除します。
例: [1, 2, 3] から先頭を削除すると → [2, 3]
let arr = [1, 2, 3];
arr.shift();
実行結果
[2, 3]


unshift は配列の先頭に要素を追加します。
例: [2, 3] の先頭に 0 を追加すると → [0, 2, 3]
let arr = [2, 3];
arr.unshift(0);
実行結果
[0, 2, 3]9.2 `splice` / `slice`



開始位置:どのインデックスから処理を始めるか
削除する数:そこからいくつ削除するか
追加する要素:削除した場所に挿入する要素
array.splice(開始位置, 削除する数, 追加する要素1, 追加する要素2, ...)


1 → index1(つまり「2」の位置)から始める
2 → そこから2つ削除(「2」と「3」が消える)
99 → その場所に 99 を挿入
let arr = [1, 2, 3, 4, 5];
arr.splice(1, 2, 99);


arr.splice(1, 2, 99) の動きを説明します。
まず、let arr = [1, 2, 3, 4, 5]; という配列があります。
• インデックス1 は要素「2」の位置を指します。したがって処理の対象は「2, 3, 4, 5」であり、先頭の「1」は対象外です。
• 2 は「そこから2つ削除する」という意味なので、「2」と「3」が削除されます。
• 99 は削除した場所に挿入する要素です。つまり「2」と「3」を削除した位置に「99」が入ります。
その結果、配列は次のように変わります。
実行結果
[1, 99, 4, 5]


1 → index1(要素「20」)から始める
3 → index3(要素「40」)の直前までで止める
つまり、index1 と index2の要素だけがコピーされる → [20, 30]
let arr2 = [10, 20, 30, 40];
let sliced = arr2.slice(1, 3);
console.log(sliced);


わかりやすく言うと、slice(1, 3) は 20から始めて、40の直前で止まります。
そのため対象になるのは「20」と「30」で、「40」は含まれません。
よって実行結果は [20, 30] になります。
実行結果
[20, 30]9.3 `concat` / スプレッド構文 `…`



要するに、concat は配列と配列を組み合わせて新しい配列を返すメソッドです。
a は [1, 2]、b は [3, 4]
a.concat(b) によって a と b が結合され、新しい配列 c が作られる。
console.log(c) を実行すると [1, 2, 3, 4] が表示される。
let a = [1, 2];
let b = [3, 4];
let c = a.concat(b);
console.log(c);
実行結果
[1, 2, 3, 4]


…a は「配列 a の中身を展開する」という意味です。
[…a, …b] と書くと、一見すると配列を組み合わせているように見えますが、実際には a の要素の後に b の要素を並べているだけ です。つまり「a の隣に b を置く」イメージです。
let a = [1, 2];
let b = [3, 4];
let d = [...a, ...b];
console.log(d);
実行結果
[1, 2, 3, 4]10. 検索・判定メソッド


10.1 `includes`



fruits の配列には [“apple”, “banana”, “orange”] が入っています。
console.log(fruits.includes(“banana”)); は、この配列の中に “banana” が含まれているかどうかを調べます。
結果として “banana” は配列に含まれているので、true が返されます。
let fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("banana"));
実行結果
true


このコードは、fruits の中に “grape” が含まれているかどうかを調べます。
しかし、fruits には “grape” が含まれていないため、結果は false になります。
let fruits = ["apple", "banana", "orange"];
console.log(fruits.includes("grape"));
実行結果
false10.2 `some` / `every`



つまり、1つでも条件を満たせば true、1つも満たさなければ false になります。
n > 4 は「4より大きい数字があるかどうか」を調べています。
numbers の中では 5 が 4 より大きいため、結果は true になります。
let numbers = [1, 2, 3, 4, 5];
console.log(numbers.some(n => n > 4));
実行結果
true


つまり、すべての要素が条件を満たせば true、1つでも満たさなければ false になります。
n > 0 は「0より大きい数字かどうか」を調べています。
numbers の中のすべての要素が 0 より大きいため、結果は true になります。
let numbers = [1, 2, 3, 4, 5];
console.log(numbers.every(n => n > 0));
実行結果
true11. 反復処理と変換


11.1 `filter`



要するに、次のコードを見ると「2で割り切れる数字(偶数)」だけが抽出されているのがわかります。つまり、条件を満たす要素だけを取り出すということです。
nums には 1 から 5 までの数字が入っています。
nums.filter(n => n % 2 === 0);
このコードは、nums の中から「2で割ったときに余りが出ない数字」を抽出します。実行すると、条件を満たす数値は [2, 4] だとわかります。
let nums = [1, 2, 3, 4, 5];
let evens = nums.filter(n => n % 2 === 0);
実行結果
[2, 4]


ここで出てくる n は、配列の要素を一つずつ受け取る仮の変数名です。慣習的に number の略として n がよく使われますが、決まりはなく、num や value など自由に名前を変えることができます。
要するに、ここでの n は配列の要素を順番に受け取るための仮の名前です。
このように仮の変数を使うことで、配列の要素を一つずつ処理するコードをシンプルに短く書けるように設計されています。
もし n のような仮の変数を使わなければ、同じ処理をするのにもっと長いコードを書かなくてはなりません。
11.2 `reduce`



nums に [1, 2, 3, 4] があるとします。
reduce を使うと、すべての要素を合計して結果は 10 になります。
let nums = [1, 2, 3, 4];
let sum = nums.reduce((acc, cur) => acc + cur, 0);
実行結果
10


acc は「これまでの計算結果」
cur は「現在の要素」
初期値 0 から始めて、順番に足し合わせていく
acc と cur という名前は決まりではありません。自由に名前をつけられますが、慣習的にこの書き方がよく使われます。



簡単にいうと、
[1, 2, 3, 4] の場合、「1 を計算し終えたから次は 2」「2 を足したから次は 3」というように、acc に途中結果が入り、cur が [1, 2, 3, 4]を順番に処理されていきます。
1. 初期値 0 が acc に入る
◦ cur = 1 → acc + cur = 0 + 1 = 1
2. 次の要素
◦ acc = 1, cur = 2 → 1 + 2 = 3
3. 次の要素
◦ acc = 3, cur = 3 → 3 + 3 = 6
4. 次の要素
◦ acc = 6, cur = 4 → 6 + 4 = 10


最終的に acc が 10 になり、それが reduce の戻り値になります。
12. 配列の並び替え


12.1 `sort`



sort() は 要素を文字列に変換して、文字コード(辞書順)で比べるんです。
• “10” → 先頭が “1”
• “2” → 先頭が “2”
• “30” → 先頭が “3”
この「先頭の文字」を比べるので、
“1” → “2” → “3” の順番になり、結果が [10, 2, 30] になるんです。
let nums = [10, 2, 30];
nums.sort();
console.log(nums);
[10, 2, 30]


(a, b) => a – b を渡したときの sort は、「小さい数から順番に並べる(昇順)」 という動きをします。
裏側では「a – b が負なら a が先、正なら b が先」というルールで比較してるんですが、実際に使うときは「小さい順に並ぶ」と覚えておけば十分です。
let nums = [10, 2, 30];
nums.sort((a, b) => a - b);
console.log(nums);
[2, 10, 30]12.2 `reverse`



reverse を使うと、配列の要素を逆の順番に並べ替えます。
let arr = [1, 2, 3];
arr.reverse();
[3, 2, 1]13.オブジェクト配列の操作



次のような users 配列があります。
let users = [
{ id: 1, name: "Taro" },
{ id: 2, name: "Hanako" },
{ id: 3, name: "Ken" }
];


users.find(u => u.id === 2); は、id が 2 の要素を探す という意味です。
let user = users.find(u => u.id === 2);
console.log(user);


users の中から 2 の要素が見つかったので、実行結果は { id: 2, name: “Hanako” } になります。
実行結果
{ id: 2, name: "Hanako" }14. 応用テーマ
多次元配列



配列の中にさらに配列を入れることができます。これを 多次元配列 と呼びます。
let matrix = [
[1, 2],
[3, 4],
[5, 6]
];


さらに、二重のインデックスでアクセスできます。
matrix[1] → [3, 4]
その [0] → 3
matrix[1] はインデックス 1 の要素なので [3, 4] です。
さらにその [0] を指定すると、[3, 4] の先頭要素である 3 が取り出せます。
したがって実行結果は 3 になります。
console.log(matrix[1][0]);
実行結果
3コラム:実務でのインデックス活用を会話で学ぼう!



以上がインデックスの説明でした。どう思いますか?



いや、インデックスの説明を長々と書いてますけど、優秀な人ってそんなに細かいこと覚えないんですよ。結局 indexOf() で“最初に見つかった位置を返す”、見つからなければ -1 になる。これだけ知ってれば実務で困らないんですよね。
で、初心者が混乱するのは“0から始まる”ってところだけ。そこを一度理解すれば、配列も文字列も同じルールで扱えるんで、わざわざ刑務所の例えとか出さなくてもいいんですよね。
優秀な人は、複雑な例え話や冗長な説明を使わずに、“シンプルで再利用できるルール”を押さえるんですよ。だから indexOf() を一行で理解して、必要なら findIndex や lastIndexOf に広げる。それが効率的なんですよ。
つまり、優秀な人は“全部覚える”んじゃなくて、“使える最小限”を押さえて応用するんです。



つまり、まずは indexOf() のような基本的な使い方を少しずつ覚えていき、慣れてきたら findIndex() や lastIndexOf() など、条件検索や応用的なインデックス操作にステップアップしていけばいいんだよね。



まぁそうなんですよね。最初は indexOf() だけ覚えておけば十分で、慣れてきたら findIndex() とか lastIndexOf() とかに広げていけばいい。結局、優秀な人って“全部一気に覚える”んじゃなくて、“必要なときに必要なものを追加していく”んですよ。だから、そのステップアップの仕方は正しいと思いますよ。
まとめ


インデックス(index)とは、配列や文字列などの要素にアクセスするための「位置番号」です。
JavaScript では 0から始まる ことが大きな特徴で、データ操作の基盤となる考え方です。
本記事では、以下の観点からインデックスを解説しました。
復習してみましょう!
1. 基本概念
• 人間は 1 から数えるが、JavaScript のインデックスは 0 から始まる
• 配列や文字列の要素にアクセスする際に使う
• インデックスがあることで、複数のデータを効率的に管理できる



インデックスがなければ、配列の中の要素を扱うたびに fruit1, fruit2, fruit3… のように個別の変数を用意しなければならず、コードは長くなり紛らわしいものでした。
そこで インデックスという仕組みが導入され、配列や文字列を「位置番号」で扱えるようになったのです。
このおかげでコードは短く、読みやすくなり、JavaScriptを使う人にとっても大きな利便性をもたらしました。
2. 配列とインデックス
• fruits[0] → “apple” のように要素を取り出せる
• fruits[1] = “orange” のように更新も可能
• array.length – 1 で最後の要素にアクセスできる



fruits を使えば、インデックス番号で要素を取り出すことができます。
また、配列の最後の要素を取り出したい場合は array.length – 1 を指定します。
こうした基本を覚えておくと、コードをシンプルかつ効率的に書けるようになります。
3. 文字列とインデックス
• “JavaScript”[0] → “J”
• “JavaScript”[word.length – 1] → “t”
• 文字列はイミュータブルなので直接変更はできず、新しい文字列を作り直す必要がある



イミュータブル(変更できない)については以前も説明しましたが、もし忘れていたらここで思い出してください。
つまり、文字列の中身を直接書き換えることはできず、新しい文字列を作り直す必要があります。
4. インデックス検索メソッド
• indexOf / lastIndexOf → 要素の位置を検索
• findIndex → 条件に合う最初の要素の位置を返す



配列の中に要素がたくさんある場合、indexOf や lastIndexOf を使えば、特定の要素がどの位置にあるかを簡単に調べられます。
また、findIndex を使えば「条件に合う最初の要素の位置」を取得できます。
これらのメソッドを活用することで、検索処理をシンプルに書けるのが便利なポイントです。
5. ループとインデックス
• forループで i を使って順番に処理
• forEachで (item, index) を受け取り、シンプルに書ける



柔軟に制御したいならfor。シンプルに書きたいならforEach。
6. オブジェクトとインデックス的アクセス
• Object.keys(obj)でキーを配列化し、インデックスでアクセス可能
• user[keys[0]]のように「キーを経由して値を取り出す」ことができる



Object.keys(obj) は、オブジェクトのキーを配列としてまとめて取り出せます。
そして user[keys[0]] のように書くと、そのキーに対応する値を取り出すことができます。
7. Map / Set とインデックス
• map.keys()はイテレーターで、そのままではインデックスアクセス不可
• […map.keys()]とスプレッド構文で配列化すれば要素の[1]のようにアクセスできる
• Setも順序を保持するが、直接インデックス指定はできない



インデックスアクセスをしたい場合は、map.keys()のままではできません。
スプレッド構文を使って […map.keys()] のように配列化すれば、要素の[1]のようにインデックス指定で要素を取り出せるようになります。
8. 配列操作メソッドとインデックス
• push / pop / shift / unshift → 先頭・末尾の追加削除
• splice / slice → 部分的な削除・コピー
• concat / スプレッド構文 … → 配列の結合



これらのメソッドを上手く使えると、配列を自在に操作できるようになり、より高度なコードを書けるようになります。
イメージしやすいようにゲームに例えると:
• push:ゾンビが次々と現れる → 配列の末尾に追加
• pop:倒した敵を消す → 配列の末尾を削除
• shift:先頭のキャラが退場する → 配列の先頭を削除
• unshift:新しい仲間が先頭に加わる → 配列の先頭に追加
• splice:敵を途中からまとめて消す、または差し替える → 部分的に削除・置換
• slice:ステージの一部だけ切り出す → 部分配列をコピー
9. 検索・判定
• includes → 要素が含まれているかを真偽値で返す
• some / every → 条件を満たす要素があるか/すべて満たすか



人狼ゲームに例えるとわかりやすいです。
includes:占い師が生存者リストを調べて、人狼が含まれているかを確認する。
some:プレイヤーの中に「人狼が1人でもいるか」を判定する。
every:全員が市民かどうかを確認する。
10. 反復処理と変換
• filter → 条件に合う要素だけを抽出
• map → 要素を変換して新しい配列を作成
• reduce → 配列全体を 1 つの値に集約



例えば、filter を使えば「大卒の人だけ」を抽出できます。
map を使えば「学歴の一覧」だけを新しい配列として作れます。
さらに reduce を使えば「全員の年齢を合計する」といった集約処理ができます。
11. 並び替えと反転
• sort → デフォルトは文字列比較、数値は比較関数を指定
• reverse → 配列を逆順に並べ替える



reverse を使うと、配列の順番をひっくり返せます。
例えば「ゾンビから人間に復活する」ように状態を逆転させたり、「古いPCから新しいPCへ」と順序を逆にするイメージです。
sort を使うと、配列を並び替えられます。
例えば「年齢順に並べる」「名前をアルファベット順に並べる」といった使い方ができます。
12. 応用テーマ
• オブジェクト配列:findで条件検索
• 多次元配列:matrix[1][0] のように二重のインデックスでアクセス



多次元配列では、matrix[1][0]のようにインデックスを二重に指定してアクセスします。
「二重インデックス=2回行動」と考えると、イメージしやすく覚えやすいでしょう。
インデックスを理解する意義
インデックスを正しく理解すれば、
• 配列や文字列の操作が直感的にできる
• 検索や更新処理を効率的に書ける
• オブジェクトや Map/Set、多次元配列など幅広いデータ構造を自在に扱える
つまり、インデックスは JavaScriptのデータ操作を支える基礎概念です。



ぜひ実際に手を動かして試してくださいね、頑張ってくださいね!
名言
やってみなはれ。やらなわかりまへんで
この記事が参考になったと感じたら、ぜひシェアやコメントで教えてください。
今後の改善に役立てます。最後まで読んでいただき、ありがとうございました。














コメント