JavaScript / LESSON 06 / JS06

JavaScript:配列の基本操作

1学習の目的

2基礎解説

やりたいこと書き方注意点
末尾に追加/削除push() / pop()元の配列を書き換える
一部を切り出すslice(1, 3)元は無傷。1以上3未満
含まれるか調べるincludes("値")true / false を返す
数値を並べ替えるsort((a, b) => a - b)比較関数が必須
✅ 覚えるべき重要ポイント
  1. 番号は0始まり。末尾は items[items.length - 1]items.at(-1)。個数は items.length(カッコ不要)。
  2. sort() をそのまま数値に使うと壊れる。文字列として比較されるため [10, 9, 100][10, 100, 9] になる。数値は必ず sort((a, b) => a - b) と書く。
  3. slice元を変えずコピーを返すsplice元を書き換える。名前が似ているが性質は正反対。
  4. sort reverse push元の配列を変更する。元を残したいときは [...items].sort(…) のようにコピーしてから操作する。
  5. スプレッド構文 [...a, ...b] で連結やコピーができる。const copy = items;コピーではなく同じ配列を指すので、片方を変えるともう片方も変わる。

現場使用例:APIから受け取った一覧の保持、ランキングの並べ替え、カートへの商品追加 cart.push(item)、上位3件の切り出し sorted.slice(0, 3)

const items = ["りんご", "みかん", "ぶどう"];

console.log(items[0]);          // りんご
console.log(items.at(-1));      // ぶどう(末尾)
console.log(items.length);      // 3

items.push("もも");             // 末尾に追加
console.log(items);             // ['りんご','みかん','ぶどう','もも']

console.log(items.slice(0, 2)); // ['りんご','みかん'] 元は無傷
console.log(items.includes("みかん"));  // true

// 数値の並べ替えは比較関数が必須
const nums = [10, 9, 100, 1];

console.log([...nums].sort());              // [1, 10, 100, 9] ← 壊れる
console.log([...nums].sort((a, b) => a - b)); // [1, 9, 10, 100] ← 正しい

3基本ドリル(10問)

JS06-D01 fruits = ["りんご", "みかん", "ぶどう"] の最初最後の要素を、この順に1行ずつ出力せよ。 コーディング★☆☆無料
期待される結果

出力 == りんご / ぶどう(2行)

ヒント

先頭は [0]、末尾は at(-1) で取り出せる。

模範解答
const fruits = ["りんご", "みかん", "ぶどう"];

console.log(fruits[0]);
console.log(fruits.at(-1));
解説

at(-1) なら要素が何個でも末尾が取れる。fruits[fruits.length - 1] と書いても同じだが、こちらのほうが短い。

JS06-D02 items = ["a", "b", "c", "d"] のとき items[2] の値はどれか。
A. "b" B. "c" C. "d" D. エラー
選択★☆☆無料
期待される結果

解答 == B

ヒント

番号は0から数える。

模範解答
B
解説

0番が "a"、1番が "b"、2番が "c"。「2番目」と「番号2」は違うという点が初学者最大の混乱ポイント。

JS06-D03 nums = [1, 2, 3] の末尾に 4 を追加し、配列全体を出力せよ。 コーディング★☆☆無料
期待される結果

出力 == [ 1, 2, 3, 4 ]

ヒント

push() を使う。戻り値ではなく配列自体を出力する。

模範解答
const nums = [1, 2, 3];
nums.push(4);
console.log(nums);
解説

push の戻り値は追加後の要素数なので、nums = nums.push(4) と書くと 4 という数字が入ってしまう。代入しないのが正解。

JS06-D04 配列の要素数を出力するコードを完成させよ。 穴埋め★☆☆無料
コード
const colors = ["赤", "青", "黄"];
console.log(colors.____);
期待される結果

出力 == 3

ヒント

個数を表すプロパティ。カッコは付けない。

模範解答
length
解説

length はプロパティなのでカッコ不要。文字列にも使えて文字数が取れる。メソッドと混同して length() と書くのがよくあるミス。

JS06-D05 nums = [10, 20, 30, 40, 50] のとき nums.slice(1, 3) の結果はどれか。
A. [20, 30] B. [20, 30, 40] C. [10, 20, 30] D. [30, 40]
選択★☆☆無料
期待される結果

解答 == A

ヒント

開始は含む、終了は含まない。

模範解答
A
解説

番号1(20)から始まり、番号3(40)の手前まで。JS05の i < 5 と同じ「未満」の考え方。

JS06-D06 scores = [72, 95, 61, 88] を大きい順に並べ替えて出力せよ。 コーディング★★☆無料
期待される結果

出力 == [ 95, 88, 72, 61 ]

ヒント

数値の降順は sort((a, b) => b - a)。比較関数を省略してはいけない。

模範解答
const scores = [72, 95, 61, 88];
console.log(scores.sort((a, b) => b - a));
解説

昇順は a - b、降順は b - a。この2つは丸暗記でよい。比較関数を省くと文字列として比較され、意図しない順序になる。

JS06-D07 items に "みかん" が含まれるかを判定するコードを完成させよ。 穴埋め★★☆無料
コード
const items = ["りんご", "みかん", "ぶどう"];
console.log(items.____("みかん"));
期待される結果

出力 == true

ヒント

「含む」を意味する英単語。true / false を返す。

模範解答
includes
解説

indexOf でも調べられるが「見つからないと -1」という戻り値を覚える必要がある。有無だけ知りたいなら includes のほうが読みやすい

JS06-D08 [10, 9, 100, 1].sort() の結果はどれか。
A. [1, 9, 10, 100] B. [1, 10, 100, 9] C. [100, 10, 9, 1] D. エラー
選択★★☆無料
期待される結果

解答 == B

ヒント

比較関数がないとき、要素は何として比較されるか。

模範解答
B
解説

文字列として比較されるため "10" < "100" < "9" という並びになる。数値のソートで比較関数を忘れるのは、JavaScriptで最も有名なバグのひとつ。

JS06-D09 nums = [12, 45, 7, 23] の合計最大値を、この順に1行ずつ出力せよ(for...of と Math.max を使ってよい)。 コーディング★★☆無料
期待される結果

出力 == 87 / 45(2行)

ヒント

合計は let total = 0 で積み上げる。最大値は Math.max(...nums) とスプレッド構文で渡せる。

模範解答
const nums = [12, 45, 7, 23];

let total = 0;
for (const n of nums) {
  total += n;
}

console.log(total);
console.log(Math.max(...nums));
解説

Math.max(nums) では配列そのものを渡してしまい NaN になる。スプレッド構文で展開して個々の数値として渡す必要がある。

JS06-D10 scores = [72, 95, 61, 88, 79] を大きい順に並べ、上位3件だけを配列として出力せよ。元の配列は変更しないこと コーディング★★☆無料
期待される結果

出力 == [ 95, 88, 79 ]

ヒント

[...scores] でコピーしてから sort し、slice(0, 3) で先頭3件を取る。

模範解答
const scores = [72, 95, 61, 88, 79];
console.log([...scores].sort((a, b) => b - a).slice(0, 3));
解説

並べ替え → 先頭を切り出すでランキング上位N件が1行で書ける。sort は元を壊すので、[...scores] のコピーを挟むのが安全な作法。

4実践シナリオ(5問)

JS06-S01 【買い物リスト】items = ["牛乳", "卵", "パン"] に "バター" を追加し、"卵" を削除したうえで、番号付きで1行ずつ出力し、最後に「合計3点」と出力せよ。 コーディング★★☆無料
期待される結果

3行の番号付きリスト+最終行 合計3点

ヒント

追加は push。削除は indexOf で位置を調べてから splice(位置, 1)。出力は entries() で番号を振る。

模範解答
const items = ["牛乳", "卵", "パン"];

items.push("バター");
items.splice(items.indexOf("卵"), 1);

for (const [i, item] of items.entries()) {
  console.log(`${i + 1}. ${item}`);
}

console.log(`合計${items.length}点`);
解説

splice(位置, 個数) は指定位置から指定数を削除する。値を指定して消す機能はないので、indexOf で位置を求めてから渡すのが定番の組み合わせ。

JS06-S02 【成績表】names = ["佐藤", "鈴木", "高橋"]、scores = [82, 95, 67] の2本の配列がある。「佐藤:82点」の形式で3行出力し、最後に「平均:81.3点」と小数1桁で出力せよ。 コーディング★★☆無料
期待される結果

3行の成績+最終行 平均:81.3点

ヒント

entries() の番号 i を使って scores[i] を引く。平均は toFixed(1) で小数1桁の文字列になる。

模範解答
const names = ["佐藤", "鈴木", "高橋"];
const scores = [82, 95, 67];

for (const [i, name] of names.entries()) {
  console.log(`${name}:${scores[i]}点`);
}

let total = 0;
for (const s of scores) {
  total += s;
}

console.log(`平均:${(total / scores.length).toFixed(1)}点`);
解説

2本の配列を同じ順番で対応させる「並行配列」。番号でひも付けるので順序がズレると壊れるのが弱点。次章のオブジェクトでこの弱点を解消する。

JS06-S03 【売上ランキング】sales = [120, 340, 210, 450, 180](単位:万円)の上位3件を「1位:450万円」の形式で出力せよ。 コーディング★★☆無料
期待される結果

3行。1位:450万円 / 2位:340万円 / 3位:210万円

ヒント

[...sales].sort((a, b) => b - a).slice(0, 3) で上位3件を作り、entries() で順位を振る。

模範解答
const sales = [120, 340, 210, 450, 180];

const top3 = [...sales].sort((a, b) => b - a).slice(0, 3);

for (const [i, s] of top3.entries()) {
  console.log(`${i + 1}位:${s}万円`);
}
解説

D10の「上位N件」とJS05の entries() を組み合わせた形。ランキング表示はこの2手で必ず作れる

JS06-S04 【重複の除去】orders = ["A", "B", "A", "C", "B", "A"] から、登場した順を保ったまま商品を重複なく取り出し、それぞれの件数を「A:3件」の形式で出力せよ。 コーディング★★★無料
期待される結果

3行。A:3件 / B:2件 / C:1件

ヒント

空の配列を用意し、includes で「まだ入っていなければ push」する。件数は for...of で数えるか、絞り込んだ長さで求める。

模範解答
const orders = ["A", "B", "A", "C", "B", "A"];

const unique = [];

for (const o of orders) {
  if (!unique.includes(o)) {
    unique.push(o);
  }
}

for (const u of unique) {
  let count = 0;
  for (const o of orders) {
    if (o === u) {
      count++;
    }
  }
  console.log(`${u}:${count}件`);
}
解説

includes で重複を防ぐのは定番テクニック。ただしループが二重になっていて効率がよくない。次章のオブジェクトを使うと1回のループで書けるようになる。

JS06-S05 【元の配列を壊さない】scores = [72, 95, 61] について、次の3行を出力せよ。
「ソート後(コピー):[95,72,61]」(降順)
「元の配列:[72,95,61]」(変わっていないこと
「連結:[72,95,61,100]」(スプレッド構文で 100 を足した新しい配列)
※配列は JSON.stringify() で文字列にして表示すること
コーディング★★★無料
期待される結果

出力3行が完全一致

ヒント

コピーは [...scores]。連結も [...scores, 100] で新しい配列が作れる。どちらも元の scores は変わらない。

模範解答
const scores = [72, 95, 61];

const sorted = [...scores].sort((a, b) => b - a);
const added = [...scores, 100];

console.log(`ソート後(コピー):${JSON.stringify(sorted)}`);
console.log(`元の配列:${JSON.stringify(scores)}`);
console.log(`連結:${JSON.stringify(added)}`);
解説

スプレッド構文はコピーを作る道具const copy = scores; と書くと同じ配列を指すだけなので、copy を変更すると scores も変わってしまう。元データを守りたい場面では必ず [...] を挟む。

5仕上げ課題

JS06-FINAL 【在庫レポート】商品名と在庫数の2本の配列から、明細と集計を出力するコードを書け。

const products = ["ボールペン", "ノート", "消しゴム", "ファイル", "付箋"];
const stocks = [120, 8, 45, 3, 67];
const threshold = 10;


仕様:
① 各商品を「1. ボールペン:120個」の形式で出力。在庫が threshold 未満の商品は末尾に「 ⚠発注」を付ける
② 明細の後に --- の行を出す
③ 総在庫と品目数を1行で出す
④ 要発注の品目数と商品名(読点区切り)を1行で出す
⑤ 在庫が多い順の上位3商品名を1行で出す(元の配列を壊さないこと

出力仕様(10行):
=== 在庫レポート ===
1. ボールペン:120個
2. ノート:8個 ⚠発注
3. 消しゴム:45個
4. ファイル:3個 ⚠発注
5. 付箋:67個
---
総在庫:243個 / 品目数:5
要発注:2品目(ノート、ファイル)
在庫トップ3:ボールペン、付箋、消しゴム
期待される結果

出力10行が完全一致

ヒント

entries() の番号 i で stocks[i] を引く。要発注の商品名は空配列に push で集め、join("、") でつなぐ。トップ3は [...stocks] をコピーして降順ソートし、上位3つの在庫数それぞれについて indexOf で products の名前を引く。

模範解答
const products = ["ボールペン", "ノート", "消しゴム", "ファイル", "付箋"];
const stocks = [120, 8, 45, 3, 67];
const threshold = 10;

console.log("=== 在庫レポート ===");

const low = [];
let total = 0;

for (const [i, name] of products.entries()) {
  const stock = stocks[i];
  total += stock;

  const mark = stock < threshold ? " ⚠発注" : "";

  if (stock < threshold) {
    low.push(name);
  }

  console.log(`${i + 1}. ${name}:${stock}個${mark}`);
}

const top3 = [...stocks].sort((a, b) => b - a).slice(0, 3);
const topNames = [];

for (const s of top3) {
  topNames.push(products[stocks.indexOf(s)]);
}

console.log("---");
console.log(`総在庫:${total}個 / 品目数:${products.length}`);
console.log(`要発注:${low.length}品目(${low.join("、")})`);
console.log(`在庫トップ3:${topNames.join("、")}`);
解説

2本の並行配列を番号でひも付けながら、1回のループで明細と集計を同時に作るのが要点。indexOf は「値から番号を逆引き」する道具で、ソート後の在庫数から商品名を復元するのに使っている。

そして⑤の「元の配列を壊さない」が最重要だ。stocks.sort() と書いてしまうと stocks 自体が並び替わり、その後の indexOf が別の商品を指してしまう[...stocks] のコピーを挟むだけでこの事故は防げる。

ただしこのコードには限界もある。商品名と在庫数が別々の配列なので、片方だけ並べ替えると対応が崩れる。次章のオブジェクトを使えば、名前と在庫を1つにまとめて安全に扱えるようになる。