JavaScript | 配列の中身を検索(indexOf / lastIndexOf)

JavaScript JavaScript
スポンサーリンク

練習問題(解答付き) — indexOf / lastIndexOf をしっかり練習しよう

以下は初心者〜中級者向けの練習問題(合計8問)。各問題に「問題」「期待される出力」「解答コード」「解説」「よくある間違い」を付けています。自分でまず考えてから答えを確認してください。


初級:問題1

問題
配列 ['cat','dog','rabbit','dog'] の中で、dog の最初の出現位置と最後の出現位置をコンソールに出力しなさい。

期待される出力

1
3

解答コード

const animals = ['cat','dog','rabbit','dog'];
console.log(animals.indexOf('dog'));     // 1
console.log(animals.lastIndexOf('dog')); // 3
JavaScript

解説
indexOf は左(先頭)から見つかる最初のインデックス、lastIndexOf は右(末尾)から見つかる最初=配列全体で最後に現れる位置を返す。配列は 0 始まりなので 'dog' は 1 と 3。

よくある間違い

  • indexOflastIndexOf の意味が逆になってしまう(頭と末尾を取り違える)。
  • インデックスが 1 始まりだと勘違いする。

初級:問題2

問題
配列 [5,3,5,7,3]3 が存在するかを調べ、あれば "ある", なければ "ない" を出力しなさい。(indexOf を使うこと)

期待される出力

ある

解答コード

const arr = [5,3,5,7,3];
console.log(arr.indexOf(3) !== -1 ? 'ある' : 'ない');
JavaScript

解説
indexOf が見つからないと -1 を返すので、!== -1 のチェックで存在確認ができる(includes を使えばより直感的)。

よくある間違い

  • if (arr.indexOf(3)) のように書いてしまうと、indexOf0 のとき false 扱いになって誤判定になる。

初級:問題3

問題
配列 ['a','b','a','c','b'] から重複を取り除き [ 'a','b','c' ] にするコードを filterindexOf だけで書きなさい。

期待される出力

['a','b','c']

解答コード

const arr = ['a','b','a','c','b'];
const uniq = arr.filter((v, i, self) => self.indexOf(v) === i);
console.log(uniq); // ['a','b','c']
JavaScript

解説
filter のコールバックで「その要素が配列で最初に出現する位置(indexOf(v))」と現在のインデックス i を比較する。等しければ初出なので残す。

よくある間違い

  • indexOfarr.indexOf(v) と書くが、filter 内で参照する配列は第三引数 self を使した方が汎用的(現状は arr でも動く)。

中級:問題4

問題
配列 ['x','y','x','z'] から最初に出てくる 'x' を削除して、結果の配列を出力しなさい。(indexOfsplice を使うこと)

期待される出力

['y','x','z']

解答コード

const arr = ['x','y','x','z'];
const idx = arr.indexOf('x');
if (idx !== -1) arr.splice(idx, 1);
console.log(arr); // ['y','x','z']
JavaScript

解説
indexOf で削除したい要素のインデックスを取得し、それを splice(index, 1) で消す。splice は配列を直接変更する(破壊的操作)。

よくある間違い

  • slice と混同して slice(idx, 1) と書いてしまう(slice は破壊しないし引数の意味が違う)。

中級:問題5

問題
配列 [1,2,3,2,1] の中で 2 が最後に出てくる位置(インデックス)を求め、その位置以降(その要素も含めて)を新しい配列として切り出しなさい。(lastIndexOfslice を使う)

期待される出力

[2,1]

解答コード

const arr = [1,2,3,2,1];
const idx = arr.lastIndexOf(2);
const result = idx !== -1 ? arr.slice(idx) : [];
console.log(result); // [2,1]
JavaScript

解説
lastIndexOf で最後の 2 の位置(この場合 3)を取得し、slice(3) でそのインデックスから末尾までを切り出す。slice は非破壊で新しい配列を返す。

よくある間違い

  • lastIndexOf の第2引数の意味を誤解して lastIndexOf(2, 1) のように書き、期待通りに見つからないことがある。

中級:問題6(実用)

問題
配列 ['red','green','blue']'green' があるなら削除して、なければ 'green' を先頭に追加する処理を書きなさい(indexOfsplice / unshift を使う)。

期待される出力(初期配列の場合)

['red','blue']   // 'green' を見つけて削除した結果

解答コード

const colors = ['red','green','blue'];
const idx = colors.indexOf('green');
if (idx !== -1) {
  colors.splice(idx, 1); // 見つかれば削除
} else {
  colors.unshift('green'); // 見つからなければ先頭に追加
}
console.log(colors);
JavaScript

解説
indexOf で存在チェック→存在すれば splice で削除、存在しなければ unshift(先頭追加)で挿入。実用ではトグル(存在なら削除、なければ追加)としてよく使う。

よくある間違い

  • splice(idx) と引数を1つだけ指定してしまい、以降すべての要素を削除してしまう(削除数を必ず指定する)。

上級:問題7(応用)

問題
オブジェクトの配列 [{id:1},{id:2},{id:1}] がある。id === 1 を持つ最初のオブジェクトのインデックスを取得しなさい。ただし indexOf は使えない(ヒント:findIndex を使うと簡単)。

期待される出力

0

解答コード

const list = [{id:1},{id:2},{id:1}];
const idx = list.findIndex(item => item.id === 1);
console.log(idx); // 0
JavaScript

解説
indexOf はオブジェクトを参照で比較するため、中身だけで探せない。findIndex にコールバックを渡して条件(item.id === 1)を指定すると便利。findIndex は該当要素のインデックスを返す(見つからなければ -1)。

よくある間違い

  • indexOf({id:1}) としてしまう(常に -1 になるケースが多い)。

上級:問題8(トリッキー)

問題
配列 [NaN, 1, 2] の中に NaN が含まれるかを判定し、含まれていれば "NaNあり" と出力しなさい。indexOf は使わないでください(理由は説明を読むこと)。

期待される出力

NaNあり

解答コード(推奨)

const arr = [NaN, 1, 2];
if (arr.includes(NaN)) {
  console.log('NaNあり');
} else {
  console.log('NaNなし');
}
JavaScript

代替解(ES5以前や includes が無い環境向け)

const arr = [NaN, 1, 2];
const hasNaN = arr.some(v => Number.isNaN ? Number.isNaN(v) : v !== v);
console.log(hasNaN ? 'NaNあり' : 'NaNなし');
JavaScript

解説
NaN === NaNfalse なので indexOf(NaN) は見つけられない(-1 を返す)。ES6 の includesNaN を正しく検出する。ポリフィルや some + Number.isNaN / v !== vNaN だけ自分と等しくない性質を利用)で対応できる。

よくある間違い

  • indexOf(NaN) !== -1 でチェックしてしまい見つけられないことに驚く。

最後に:練習のコツ

  • まずは紙に配列のインデックス(0,1,2…)を書いて手で追ってみると挙動が分かりやすくなります。
  • indexOf はプリミティブ(文字列・数値など)向け、オブジェクト検索や条件検索は findIndex/find を使うと楽。
  • 存在チェックは indexOf(x) !== -1includes(x) のどちらか。includes のほうが読みやすく NaN も扱える。

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