B バイナンス · 世界最大級の暗号資産取引所バイナンス 登録 → AD OKX OKX · 世界の大手暗号資産取引所OKX 登録 → AD
💻 コーディングの基礎 · 第6講 / 10

配列とオブジェクト — データを入れて扱う

配列は順番のあるリストで、オブジェクトは名前(キー)で値を探すまとまりです。二つを組み合わせた「オブジェクトの配列」は表と同じで、繰り返し文や `map`・`filter`・`reduce` で合計を出したり、欲しい行を選び出したりできます。

⏱ 約24分 ✍️ 確認問題 5問 🧪 コード実習 4題 更新 2026-10-09
🎯 この講義の学習目標
  • 配列のインデックス・length・push で値を読み取り、追加できる
  • オブジェクトのプロパティをドット記法とブラケット記法で読み取り、書き換えられる
  • オブジェクトの配列を表として見て、繰り返し文や map・filter・reduce で加工できる
  • JSON.stringify と JSON.parse でデータを文字に変換し、元に戻せる

1.配列 — 順番のあるリスト

これまでは変数一つに値を一つ入れてきました。けれども、生徒30人の点数を30個の変数に入れるわけにはいきません。配列は、複数の値を順番どおりに一つの名前の下に入れるデータ型です。角かっこの中に値をカンマで並べて [70, 85, 90] のように作ります。第4講で for...of を使って一つずつ取り出したあのリストが配列です。

配列の値は、位置の番号であるインデックスで取り出します。インデックスは1ではなく0から始まるので、最初の値は arr[0]、二番目の値は arr[1] です。値の個数は arr.length で、最後の値のインデックスはいつも arr.length - 1 です。第4講で見た off-by-one の失敗は、まさにここで起きます。

存在しないインデックスを読んでもエラーにはならず、undefined が出てきます。長さが3の配列で arr[3] や arr[-1] を読むと、どちらも undefined です。後ろから数えたいときは arr.at(-1) を使えば最後の値が出てきます。配列には数値・文字列・真偽値を混ぜて入れることもできますが、実際には同じ種類の値を入れたほうが扱いやすくなります。

インデックスは0から、存在しないマスは undefined
const fruits = ['りんご', 'なし', 'みかん'];
console.log(fruits[0], fruits[2]);
console.log(fruits.length);
console.log(fruits[fruits.length - 1]);
console.log(fruits[3]);
console.log(fruits.at(-1));
出力
りんご みかん
3
みかん
undefined
みかん

2.配列を変える・探す — `push`、`pop`、`includes`、`indexOf`

push は配列の末尾に値を追加し、pop は末尾の値を取り出して返しながら配列から取り除きます。arr[1] = 'ぶどう' のようにインデックスへ直接入れて値を変えることもできます。ここで混同しやすい点があります。const で作った配列でも、中身は変えられるのです。const が防ぐのは「その名前に別の配列を入れ直すこと」であって、配列の中のマスを変えることではありません。

値が入っているかを確かめるときは、includes が真偽を、indexOf が位置を返します。indexOf は見つからなければ -1 を返します。第4講で「見つからない」を -1 で表したのと同じ約束です。そのため if (arr.indexOf(x)) のように書くと、最初のマス(0)にあるときに偽になり、見つからなかった場合(-1)は真になってしまいます(第3講の truthy・falsy)。あるかどうかだけを知りたいなら includes を使いましょう。

配列を別の変数に入れると、コピーではなく「同じ配列を指す名前」がもう一つできます。下のコードで b に push すると、a も変わります。同じ家の住所を二人で分け合ったようなものです。本当に別のコピーが必要なら、[...a] のように展開して新しい配列を作ります。オブジェクトもまったく同じように動きます。

push・pop・includes・indexOf
const cart = ['牛乳', 'パン'];
cart.push('卵');
console.log(cart, cart.length);
const last = cart.pop();
console.log(last, cart);
console.log(cart.includes('パン'), cart.indexOf('パン'));
console.log(cart.indexOf('海苔'));
出力
[ '牛乳', 'パン', '卵' ] 3
卵 [ '牛乳', 'パン' ]
true 1
-1
同じ配列を指す二つの名前 vs 展開して作ったコピー
const a = [1, 2];
const b = a;
b.push(3);
console.log(a);
const c = [...a];
c.push(4);
console.log(a, c);
出力
[ 1, 2, 3 ]
[ 1, 2, 3 ] [ 1, 2, 3, 4 ]

3.オブジェクト — 名札の付いたマス

配列が「何番目か」で値を探すなら、オブジェクトは「名前」で値を探します。波かっこの中に キー: 値 をカンマで並べて、{ name: '健太', age: 20 } のように作ります。キーと値の組の一つひとつをプロパティと言います。会員一人、商品一つのように、いくつもの情報が集まって一つの対象を成すときにオブジェクトがよく合います。

プロパティは user.name のようにドットで読むのがふつうで、キーの名前が変数に入っているときは user[key] のように角かっこで読みます。存在しないプロパティを読むと、配列の存在しないマスと同じく undefined が出てきます。ところが、その undefined からさらにプロパティを読もうとすると、今度は TypeError が出ます。下のコードがその例で、キーの名前を nmae と打ち間違えたことが原因です。メッセージの正確な文言はブラウザーによって少しずつ違います。

このエラーは、AIが書いたコードを実際のデータにつないだときに、もっともよく見るエラーの一つです。たいていは、データにあるキーの名前とコードが期待したキーの名前が違うか、一部の項目だけにそのプロパティが欠けているときに起きます。エラーメッセージのかっこ内の (reading 'length') は「何を読もうとして失敗したか」を教えてくれるので、そのすぐ前の値がなぜ undefined なのかをさかのぼって探せばよいのです(第8講)。

読む・変える・追加する、存在しないプロパティは undefined
const user = { name: '健太', age: 20 };
console.log(user.name, user.age);
user.age = 21;
user.city = '大阪';
console.log(user);
const key = 'name';
console.log(user[key]);
console.log(user.email);
出力
健太 20
{ name: '健太', age: 21, city: '大阪' }
健太
undefined
undefined からさらに読むと TypeError
const user = { name: '健太' };
console.log(user.nmae);
console.log(user.nmae.length);
出力
undefined
TypeError: Cannot read properties of undefined (reading 'length')

4.オブジェクトの配列 = 表

実際のデータの大半は「オブジェクトの配列」の形をしています。配列の各マスが表の一行で、オブジェクトのキーが列の名前です。Excel のようなスプレッドシートの表一枚をコードに移したものだと考えればよいでしょう。下の表とコードは、同じ架空の販売記録を二通りに表したものです。

この形なら、第4講の繰り返し文といま学んだプロパティの読み取りを組み合わせるだけで、ほとんどの計算ができます。行を一つずつ取り出し(for...of)、必要な列を読み(row.qty)、積み上げたり数えたりします。第9講では、テキストで書かれた表をこの形に変えて、合計・平均・グループ別の合計を実際に求めてみます。

架空の販売記録(ウォン)— 一行がオブジェクト一つ
(インデックス)`item``price``qty`
0ノート15004
1鉛筆50010
2消しゴム8003
例題上の架空の販売記録で、売上全体(価格 × 数量の合計)はいくらでしょうか。
const sales = [
  { item: 'ノート', price: 1500, qty: 4 },
  { item: '鉛筆', price: 500, qty: 10 },
  { item: '消しゴム', price: 800, qty: 3 },
];
let revenue = 0;
for (const row of sales) {
  revenue += row.price * row.qty;
}
console.log(revenue);
出力
13400
  1. ステップ1 何を積み上げるか: 売上の合計。初期値は 0。
  2. ステップ2 一行でやること: row.price * row.qty を足します。ノート6,000、鉛筆5,000、消しゴム2,400。
  3. ステップ3 結果: 6,000 + 5,000 + 2,400 = 13,400ウォン。
  4. 検算: 行が3つなので、周回も3回のはずです。行ごとに途中の合計を出力してみると、6000 → 11000 → 13400 の順に増えていきます。
答え13,400ウォン — 行ごとに価格 × 数量を積み上げる

5.`map`・`filter`・`reduce` 入門

配列には、繰り返し文の代わりになるメソッドがあります。もっともよく使う三つが map・filter・reduce です。三つとも第5講のアロー関数を受け取り、配列の値ごとにその関数を呼び出してくれます。map は値ごとに変換した結果で新しい配列を作り(長さは同じ)、filter は関数が真を返した値だけを選んで新しい配列を作り(長さは同じか短い)、reduce は値をたたみ込んで合計のような値一つを作ります。

大事なのは、map と filter が元の配列を変えずに新しい配列を返すという点です。第5講の純粋関数と同じ性質なので、結果を予測しやすくなります。reduce には二番目の引数として初期値を必ず渡しましょう。reduce((s, x) => s + x, 0) の 0 が、第4講の累積パターンの let sum = 0 にあたります。初期値を省くと、空の配列で TypeError が出ます。

はじめは繰り返し文のほうが読みやすいかもしれませんが、それでかまいません。繰り返し文でできることを短く書く方法にすぎないからです。ただ、AIが書いたコードにはこの三つが鎖のようにつながって出てくることが多いので、一段ずつ区切って途中の結果を出力しながら読む練習をしておくとよいでしょう。

map は変換、filter は選択、reduce はたたみ込み — 元の配列はそのまま
const prices = [1500, 500, 800, 12000];
const withTax = prices.map((p) => p * 1.1);
console.log(withTax.map((p) => Math.round(p)));
const cheap = prices.filter((p) => p < 1000);
console.log(cheap);
const total = prices.reduce((s, p) => s + p, 0);
console.log(total);
console.log(prices);
出力
[ 1650, 550, 880, 13200 ]
[ 500, 800 ]
14800
[ 1500, 500, 800, 12000 ]
三つのメソッドの比較
メソッドすること返すもの繰り返し文で言えば
map値ごとに変換する同じ長さの新しい配列新しい配列に変換した値を push
filter条件に合う値を選ぶ同じか短い新しい配列条件が真のときだけ push
reduce一つにたたみ込む値一つ(合計など)累積パターン

6.JSON — データをやり取りするための文字の形式

JSONは、オブジェクトや配列を文字(文字列)で書き表す形式です。名前は JavaScript から来ていますが、いまではほとんどすべてのプログラミング言語やウェブサービスがデータのやり取りに使っています。設定ファイル、サーバーの応答、アプリが保存するデータの多くがJSONです。JSON.stringify は値をJSONの文字に変換し、JSON.parse はJSONの文字を値に戻します。

JSONは JavaScript のオブジェクトの書き方に似ていますが、より厳格です。キーは必ずダブルクォートで囲み、文字列もダブルクォートしか使えません。最後の項目のあとのカンマは許されず、コメントも書けません。関数や undefined は入れられないので、stringify すると、オブジェクトのプロパティなら抜け落ち、配列の中なら null に変わります。規則を一つでも破ると、JSON.parse が SyntaxError を出します。

JSONが長い一行につながっていると読みにくいものです。そんなときはJSONフォーマッターのツールに貼り付ければインデントを付けてくれ、規則が崩れている場所を指摘してくれることもあります。ただし、実際の会員情報のように個人情報が入ったデータは外部のツールやAIに貼り付けず、構造だけが同じ架空のデータに置き換えて確かめてください(第10講)。

値 → JSONの文字 → また値
const item = { name: 'ノート', price: 1500, tags: ['文房具'] };
const text = JSON.stringify(item);
console.log(text);
console.log(typeof text);
const back = JSON.parse(text);
console.log(back.price + 500);
出力
{"name":"ノート","price":1500,"tags":["文房具"]}
string
2000
キーに引用符がなく、シングルクォートを使っている — JSONの規則違反
const bad = "{ name: 'ノート' }";
console.log(JSON.parse(bad));
出力
SyntaxError: Expected property name or '}' in JSON at position 2 (line 1 column 3)
JSON.stringify(値, null, 2) のように三番目の引数に2を渡すと、2文字分インデントした複数行の文字に変換してくれます。このページの練習場も複数行をそのまま表示するので、長いデータを出力して構造を確かめるときに使ってみてください。

📌 要点まとめ

  • 配列は順番のあるリスト — インデックスは0から、最後は arr.length - 1、存在しないマスは undefined
  • オブジェクトは名前(キー)で値を探すまとまり — undefined からさらにプロパティを読むと TypeError
  • 配列やオブジェクトを別の変数に入れると、コピーではなく同じものを指す
  • オブジェクトの配列は表である — 行ごとに取り出して列を読んで積み上げるか、map・filter・reduce で加工する
  • JSONはダブルクォートのキー、末尾のカンマは禁止 — stringify で文字に、parse で値に

✍️ 確認問題

まず自分で解いてから「解答と解説」を開いてください。

Q1. const a = [10, 20, 30]; で a[a.length] の値はどれでしょうか。

⭕ 正解です

❌ もう一度考えてみましょう

解答と解説
正解 ② undefined

a.length は3で、インデックスは0〜2までしかないので、a[3] は undefined です。最後の値は a[a.length - 1] です。

Q2. const list = ['a', 'b']; list.push('c'); の結果として正しいものはどれでしょうか。

⭕ 正解です

❌ もう一度考えてみましょう

解答と解説
正解 ② list は ['a', 'b', 'c'] になる

const が防ぐのは、名前に別の値を入れ直すことだけです。配列の中のマスを変えたり、push で追加したりはできます。push は末尾に追加します。

Q3. [3, 8, 1, 6].filter((x) => x > 4) の結果はどれでしょうか。

⭕ 正解です

❌ もう一度考えてみましょう

解答と解説
正解 ① [8, 6]

filter は、関数が真を返した値だけを選んで新しい配列を作ります。真偽の配列が出てくるのは、同じ関数を map に渡したときです。

Q4. 次のうち、正しいJSONはどれでしょうか。

⭕ 正解です

❌ もう一度考えてみましょう

解答と解説
正解 ④ { "name": "健太", "age": 20 }

JSONではキーも文字列もダブルクォートでなければならず、最後の項目のあとのカンマは許されません。一つ目はキーに引用符がなく、二つ目はシングルクォート、三つ目は末尾のカンマが問題です。

Q5. TypeError: Cannot read properties of undefined (reading 'price') が出ました。何から確かめるべきでしょうか。

解答と解説
解答例 .price のすぐ前の値がなぜ undefined なのか — キー名の打ち間違い、存在しないインデックス、そのプロパティが欠けた項目がないかを確かめる。

このエラーは「undefined から price を読もうとした」という意味です。問題は price ではなく、その前の値(例: items[i] や row.info)にあります。

🧪 コード実習

配列とオブジェクトを読み、オブジェクトの配列(表)から値を積み上げたり選んだりする関数を作ります。空の配列のような境界値も一緒に採点されます。

コードはこのブラウザの中の隔離された場所でだけ実行され、サーバーには送られません。ネットワークには接続できず、2秒を超えると止まります。書き換えたコードはこのブラウザにだけ保存されます。Ctrl+Enter(⌘+Enter)で実行、Tabキーは空白2つ(Escの後のTabで次へ移動)。

JavaScriptが無効なので実行はできませんが、問題・最初のコード・自動チェックの内容・解答例はそのまま読めます。

1最後の値を取り出す

配列 arr の最後の値を返す関数 lastItem(arr) を作ってください。空の配列なら null を返します。

自動チェック
  • lastItem([1,2,3])期待値 3
  • lastItem(["りんご"])期待値 "りんご"
  • lastItem([])期待値 null
  • lastItem([0,false])期待値 false
💡 ヒント

空の配列での arr[arr.length - 1] は arr[-1] なので undefined です。だから空の配列は先に別に扱います。

解答例を見る
function lastItem(arr) {
  if (arr.length === 0) {
    return null;
  }
  return arr[arr.length - 1];
}

2数量の合計

{ item, qty } の形をしたオブジェクトの配列 rows を受け取り、qty の合計を返す関数 totalQty(rows) を作ってください。空の配列なら0です。

自動チェック
  • totalQty([{"item":"ノート","qty":4},{"item":"鉛筆","qty":10}])期待値 14
  • totalQty([])期待値 0
  • totalQty([{"item":"消しゴム","qty":3}])期待値 3
  • totalQty([{"item":"a","qty":0},{"item":"b","qty":0}])期待値 0
💡 ヒント

一行はオブジェクトです。ドット記法で row.qty を読みましょう。reduce を使って一行で書くこともできます。

解答例を見る
function totalQty(rows) {
  let total = 0;
  for (const row of rows) {
    total += row.qty;
  }
  return total;
}

3条件に合う名前だけを選ぶ

{ item, price } の形をしたオブジェクトの配列 rows と基準価格 min を受け取り、価格が min 以上の行の item だけを元の順番どおりに入れた配列を返す関数 namesFrom(rows, min) を作ってください。合う行がなければ空の配列 [] です。

自動チェック
  • namesFrom([{"item":"ノート","price":1500},{"item":"鉛筆","price":500},{"item":"かばん","price":20000}], 1000)期待値 ["ノート","かばん"]
  • namesFrom([], 100)期待値 []
  • namesFrom([{"item":"鉛筆","price":500}], 500)期待値 ["鉛筆"]
  • namesFrom([{"item":"鉛筆","price":500}], 501)期待値 []
💡 ヒント

filter で行を選んでから map で名前だけを取り出す二段階です。繰り返し文で if と push を使ってもかまいません。

解答例を見る
function namesFrom(rows, min) {
  return rows
    .filter((r) => r.price >= min)
    .map((r) => r.item);
}

4項目ごとの個数を数える

文字列の配列 words を受け取り、各単語が何回出てきたかを入れたオブジェクトを返す関数 countBy(words) を作ってください。例: ['りんご', 'なし', 'りんご'] → { りんご: 2, なし: 1 }。空の配列なら空のオブジェクト {} です。

自動チェック
  • countBy(["りんご","なし","りんご"])期待値 {"なし":1,"りんご":2}
  • countBy([])期待値 {}
  • countBy(["a"])期待値 {"a":1}
  • countBy(["x","x","x","y"])期待値 {"x":3,"y":1}
💡 ヒント

キーの名前が変数 w に入っているので、ドット記法ではなく角かっこの counts[w] を使います。初めて出てきた単語は undefined です。

解答例を見る
function countBy(words) {
  const counts = {};
  for (const w of words) {
    if (counts[w] === undefined) {
      counts[w] = 1;
    } else {
      counts[w] += 1;
    }
  }
  return counts;
}

🤖 AIにはこう聞いてみましょう

コピーして [ ] の部分を自分の状況に書き換えて使います。答えはそのまま信じず、本文と比べて確かめましょう。

データを配列・オブジェクトにどう入れるか迷うとき

次の架空のデータを JavaScript の「オブジェクトの配列」に変換してください。キーの名前は英語の小文字で付け、数値は文字列ではなく数値にしてください。そのうえで、このデータでできる計算を3つ(合計・条件での選択・グループ別の数え上げ)、繰り返し文版と `map`/`filter`/`reduce` 版で並べて見せてください。データ: [架空の表を貼り付け]

`map`・`filter`・`reduce` がつながったコードが読みにくいとき

下のコードの `map`/`filter`/`reduce` の連鎖を一段ずつ区切り、段ごとに途中の結果がどんな配列や値になるかを、小さな例の入力で見せてください。同じことをする `for...of` の繰り返し文版も書いてください。コード: [貼り付け]

`JSON.parse` がエラーを出すとき

次のJSON文字列が `JSON.parse` でなぜエラーになるのか、規則違反をすべて見つけてください(引用符、末尾のカンマ、コメントなど)。直したJSONも見せてください。中身は架空の例のデータです: [貼り付け]

🧰 関連ツール

この講義で扱ったJSON・正規表現・テキストを、その場で確かめたり整えたりできるツールです。本物の個人情報やパスワードは貼り付けないでください。

参考
  • MDN Web Docs — JavaScriptガイド: インデックス付きコレクション(Indexed collections)、オブジェクトの利用(Working with objects)
  • MDN Web Docs — Array.prototype.map / filter / reduce、JSON.stringify / JSON.parse のリファレンス
  • ECMA-404(JSONデータ交換形式の標準)の一般的な規則

学習目標をすべて達成できたら完了を押しましょう。

💻 コーディングの基礎

  1. 1プログラムとは — 仕事を順番・条件・繰り返しに分ける考え方
  2. 2値・変数・データ型 — 名札を付けて値を扱う
  3. 3条件分岐 — 状況によって違う道を進む
  4. 4繰り返し — 同じことを正確に何度もさせる
  5. 5関数 — 名前を付けた小さな機械に分ける
  6. 6配列とオブジェクト — データを入れて扱う
  7. 7文字列とテキスト処理 — 文字を切り出し、探し、置き換える
  8. 8デバッグとエラーの読み方 — 赤い文字を手がかりに変える
  9. 9かんたんな自動化の例 — 表の計算とテキストの整理をコードで
  10. 10AIが書いたコードを読んで検証する — テスト・セキュリティ・ライセンス・個人情報
📚 あわせて読みたい
📊表計算の作業を人工知能で手伝わせる、数式は必ず検証→ 💻人工知能のコーディング支援の使い方と危険、セキュリティとライセンス→ 💬外国語の会話練習相手としてAIを使う→ ⚙️業務自動化のアイデア探し、AIに任せる仕事の選び方→
← AI時代の基礎学力講座