配列(Array)の定義とプログラミングにおける役割
Web開発やアプリケーション開発において、データは単独で存在することは稀です。「ユーザーリスト」「商品一覧」「ToDoタスク」「1週間の天気予報」など、関連する複数のデータはセットで扱われることがほとんどです。これらを一つ一つの変数(例えば user1, user2, user3…)で管理しようとすると、コードは膨大になり、管理も不可能になります。そこで登場するのが「配列(Array)」です。
配列とは、複数のデータを一つの「箱」に入れて管理するためのデータ構造のことです。JavaScriptにおける配列は、順序付けられたリスト(Ordered List)として機能します。これは、格納されたデータに「0番目、1番目、2番目…」という順番(インデックス)が割り振られ、その順番通りに並んでいることを意味します。この「順序がある」という性質のおかげで、私たちは「リストの最初のデータを取り出す」「リストの最後に新しいデータを追加する」「順番を並べ替える」といった操作を簡単に行うことができます。
プログラミング言語にはさまざまなデータ型が存在します。JavaScriptには数値(Number)、文字列(String)、真偽値(Boolean)、null、undefinedといった基本的なデータ型がありますが、配列はこれらとは少し異なる「複合的なデータ型」としての側面を持ちます。配列の中には、数値や文字列だけでなく、真偽値やオブジェクト、さらには別の配列(多次元配列)まで、あらゆる型のデータを混在させて格納することが可能です。
Webブラウザ上で動作するJavaScriptにおいて、配列の重要性は非常に高いです。例えば、ECサイトでカートに入れた商品情報を管理したり、SNSのタイムラインに表示する投稿データをサーバーから取得して一覧表示したりする場合、その裏側では必ず配列が使われています。配列を理解することは、静的なWebページではなく、動的にコンテンツが増減する「Webアプリケーション」を作るための第一歩と言えます。まずは「関連するデータをひとまとめにする整理棚」のようなイメージを持って、学習を進めていきましょう。
配列の作成方法と基本構文(リテラルとコンストラクタ)
JavaScriptで配列を作成するには、主に2つの方法がありますが、現在主流となっているのは「配列リテラル」を使用する方法です。リテラルとは、プログラムの中で直接値を記述する記法のことで、配列の場合は角括弧 [] を使用します。
基本的な構文は以下の通りです。 const arrayName = [値1, 値2, 値3, ...];
例えば、趣味のリストを作る場合、次のように記述します。 const hobbies = ["読書", "旅行", "映画鑑賞"]; このように、角括弧の中にデータをカンマ区切りで並べるだけで、配列が生成されます。このシンプルさがJavaScriptの魅力の一つです。データが入っていない空の配列を作成したい場合は、単に const emptyArray = []; と記述します。これは、後からデータを追加していくための準備としてよく使われます。
もう一つの方法は new Array() コンストラクタを使用する方法ですが、こちらは現在ではあまり推奨されません。記述が長くなるだけでなく、引数の渡し方によって挙動が変わるなどの直感的でない部分があるためです。初心者のうちは、シンプルで読みやすい [](配列リテラル)を使うことを徹底しましょう。
配列を宣言する際の変数宣言には、let ではなく const を使うことが一般的です。「const は定数だから、中身を変えられないのでは?」と疑問に思うかもしれません。しかし、JavaScriptにおける配列やオブジェクトの場合、const で制限されるのは「変数への再代入(箱自体の入れ替え)」であり、「箱の中身(要素)の変更」は許可されています。つまり、const list = []; と宣言しても、その配列にデータを追加したり削除したりすることは可能です。逆に list =; のように配列そのものを別の配列で上書きしようとするとエラーになります。この特性を理解し、意図しない再代入を防ぐために、配列の宣言には基本的に const を使用するのがベストプラクティスです。
インデックス(添字)を使ったデータの取得とアクセス
配列に格納されたデータ(要素)には、それぞれ「インデックス(添字)」と呼ばれる番号が割り振られています。このインデックスを使って、配列の中から特定のデータを取り出したり、書き換えたりすることができます。
ここで最も重要なルールは、「インデックスは 0 から始まる」ということです。日常生活で物を数えるときは「1つ目、2つ目…」と数えますが、プログラミングの世界では「0番目、1番目…」と数えます。つまり、配列の最初の要素にアクセスするにはインデックス 0 を指定し、2番目の要素には 1 を指定します。
データへのアクセス方法は、配列変数の後ろに角括弧を書き、その中にインデックス番号を入れます。 const names = ["太郎", "次郎", "花子"]; console.log(names); // "太郎" console.log(names); // "次郎" console.log(names); // "花子"
もし、存在しないインデックス(例えば names)を指定した場合はどうなるでしょうか。他の言語ではエラーになることもありますが、JavaScriptの場合は undefined(値が定義されていない)が返されます。JavaScriptは非常に柔軟な言語であり、エラーを出さずに処理を進めてしまう「ゆるさ」があるため、意図しない undefined が発生していないか注意が必要です。
また、配列の要素数を取得するには length プロパティを使用します。 console.log(names.length); // 3 この length プロパティは非常に便利です。配列の最後の要素を取得したい場合、インデックスは「要素数 – 1」になるため、names[names.length - 1] と記述することで、配列の長さが変わっても常に最後の要素にアクセスすることができます。インデックスの仕組みと length プロパティを組み合わせることは、配列操作の基本中の基本です。
配列要素の操作:追加・削除・変更のテクニック
作成した配列は、後から自由に変更することができます。Webアプリケーションでは、ユーザーの操作に応じてリストの中身が増えたり減ったりするため、これらの操作メソッドを覚えることは必須です。
要素の変更(上書き) インデックスを指定して値を代入することで、既存のデータを変更できます。 const colors = ["赤", "青"]; colors = "黄色"; これにより、配列は ["赤", "黄色"] に変化します。const で宣言していても、このように中身の変更は可能です。
要素の追加(push) 配列の末尾に新しいデータを追加するには push メソッドを使います。 colors.push("緑"); これで配列は ["赤", "黄色", "緑"] になります。買い物リストにアイテムを追加したり、ToDoリストにタスクを追加したりする際に頻繁に使用されます。ちなみに、配列の先頭に追加する unshift というメソッドもありますが、使用頻度は push の方が圧倒的に高いです。
要素の削除 配列の末尾からデータを削除するには pop メソッドを使います。 colors.pop(); これで末尾の “緑” が削除されます。また、特定の条件に合う要素を削除したい場合は、後述する filter メソッドなどを使って「削除したいもの以外を残す」という処理を行うことが一般的です。
これらの操作を行う際、JavaScriptの「ミュータブル(変更可能)」という性質を意識する必要があります。push や pop は、元の配列そのものを書き換えます。大規模な開発では、元のデータを保持したまま新しい配列を作りたい場面も多いため、その場合は「スプレッド構文 [...]」などを使って配列をコピーしてから操作するなどの工夫が必要になりますが、まずは基本として push による追加を確実にマスターしましょう。
ループ処理の基礎:for文による配列の走査
配列の最大のメリットは、大量のデータを一度に処理できることです。そのために使われるのが「ループ処理(繰り返し処理)」です。配列に入っているすべてのデータに対して、「画面に表示する」「計算する」といった同じ処理を行いたい場合、ループ処理を使えば数行のコードで実現できます。
最も基本的かつ伝統的なループ処理が for 文です。 for (初期化式; 条件式; 増分式) { 処理 } という構文を使います。配列と一緒に使う場合は、カウンター変数(通常は i)を 0 からスタートさせ、i が配列の長さ(length)より小さい間ループさせ、i を1ずつ増やしていく、という書き方が定石です。
const numbers = [4-8];
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
このコードの流れを追ってみましょう。
1. let i = 0 でカウンターを0にセットします。
2. i < numbers.length(つまり 0 < 5)が真なので、ブロック内の処理を実行します。numbers である 10 が表示されます。
3. 処理が終わると i++ が実行され、i が 1 になります。
4. 条件判定に戻り、1 < 5 なので numbers である 20 を表示します。
5. これを繰り返し、i が 5 になった時点で 5 < 5 が偽となるため、ループが終了します。
この for 文による制御は、繰り返しの回数を細かくコントロールできる反面、記述が少し冗長であり、インデックスの扱いを間違える(無限ループや範囲外アクセス)リスクもあります。そのため、配列の全要素を単純に処理したいだけの場合は、次章で紹介する forEach メソッドなどが好まれる傾向にあります。
モダンな繰り返し処理:forEachメソッドとコールバック関数
現代のJavaScript開発(ES6以降)において、配列のループ処理を行う際に最もよく使われるのが forEach メソッドです。for 文よりも記述がシンプルで、意図が明確になるため、可読性が高いコードを書くことができます。
forEach メソッドは、配列の各要素に対して、引数として渡した関数(コールバック関数)を一度ずつ実行します。
const fruits = ["りんご", "みかん", "バナナ"];
fruits.forEach((fruit) => {
console.log(fruit);
});
このコードでは、fruits 配列の中身が一つずつ取り出され、変数 fruit に代入された状態で、アロー関数 => { ... } の中身が実行されます。 1回目は fruit が “りんご”、2回目は “みかん”、3回目は “バナナ” となり、それぞれの値が出力されます。
for 文と比較した時のメリットは、インデックス(i)の管理や終了条件(length)の記述が不要になることです。「配列の最初から最後まで順番に処理する」ということがメソッド名からも明らかであるため、コードを読む人にとっても親切です。 また、必要であれば第二引数としてインデックスを受け取ることも可能です。 fruits.forEach((fruit, index) => { console.log(index + ":" + fruit); }); このように書けば、「0:りんご」「1:みかん」といった出力も可能です。
注意点として、forEach は break 文を使って途中でループを抜けることができません。途中で処理を中断したい場合は for 文や for...of 文を使う必要がありますが、Webアプリのデータ表示処理などでは「全データを処理する」ことが多いため、forEach が第一選択肢となることが多いでしょう。
配列データの加工と抽出:mapとfilterメソッド
配列操作には、単にループするだけでなく、データを加工したり、特定の条件で抽出したりするための強力なメソッドが用意されています。これらを使いこなせると、JavaScriptの実力が一段階上がります。代表的なのが map と filter です。
mapメソッド:新しい配列を作る map は、配列のすべての要素に対して関数を実行し、その「戻り値」を集めて「新しい配列」を作成するメソッドです。
const prices = [9, 10];
const pricesWithTax = prices.map((price) => {
return price * 1.1;
});
console.log(pricesWithTax); // [11]
forEach との違いは、forEach が「処理を実行するだけ(戻り値なし)」なのに対し、map は「加工した結果を新しい配列として返す」点です。元の配列(prices)は変更されず、新しい配列(pricesWithTax)が作られるため、データの安全性が保たれます。
filterメソッド:条件に合うものだけ残す filter は、その名の通りデータを「フィルタリング」するメソッドです。コールバック関数の中で条件式を書き、true を返した要素だけを集めた新しい配列を作ります。
const scores = [7, 8, 12, 13];
const passingScores = scores.filter((score) => {
return score >= 60; // 60点以上なら合格
});
console.log(passingScores); // [12, 13]
これにより、「合格者リストを作る」「在庫ありの商品だけ表示する」「完了済みのタスクを隠す」といった機能が簡単に実装できます。これらのメソッドは「関数型プログラミング」の考え方に基づており、Reactなどのモダンなフレームワークでは頻繁に使用されます。
配列とオブジェクトの組み合わせ:データ構造の設計
ここまで配列について学んできましたが、実際のアプリケーション開発では、配列の中に単なる数値や文字列が入っていることは稀です。多くの場合、配列の中には「オブジェクト」が格納されます。
オブジェクトとは、{ name: "太郎", age: 25 } のように、キーと値のペアで情報を管理するデータ型です。一人のユーザー情報を表現するにはオブジェクトが適していますが、複数のユーザーを管理するには配列が適しています。つまり、「オブジェクトの配列」という構造が、Webアプリにおけるデータ管理の基本形となります。
const users = [
{ id: 1, name: "佐藤", role: "admin" },
{ id: 2, name: "鈴木", role: "user" },
{ id: 3, name: "高橋", role: "user" }
];
このようにデータを構造化することで、例えば「users 配列から role が “admin” の人だけを filter で抽出する」とか、「map を使って全員の name だけを取り出したリストを作る」といった高度なデータ操作が可能になります。
この「配列の中にオブジェクトが入っている」という形式は、JSON(JavaScript Object Notation)フォーマットと非常に親和性が高く、サーバーとの通信(API)でやり取りされるデータのほとんどがこの形式です。したがって、「配列」と「オブジェクト」は対立するものではなく、組み合わせて使うものだと理解しましょう。この構造を自在に扱えるようになることが、アプリケーション開発におけるデータ操作のゴールです。
DOM操作における配列:NodeListと配列の違い
JavaScriptでWebページの要素を操作する際、document.querySelectorAll() メソッドを使うと、条件に一致する複数の要素を取得できます。このとき返ってくるデータは、一見すると配列のように見えますが、実は「NodeList」と呼ばれる別のオブジェクトです。
const items = document.querySelectorAll("li");
console.log(items); // NodeList(3) [li, li, li]
NodeListは、配列と同じようにインデックス(items)で要素にアクセスしたり、length プロパティを持っていたり、forEach メソッドを使ったりすることができます。しかし、完全な配列ではありません。そのため、配列特有のメソッドである map や filter、push などが使えない場合があります(ブラウザのバージョンにもよりますが、基本的に使えないと考えた方が無難です)。
初心者がよくつまずくポイントとして、「querySelectorAll で取得した要素に対して map を使おうとしてエラーになる」というものがあります。これを解決するには、NodeListを「本物の配列」に変換する必要があります。
変換には、スプレッド構文 [...] や Array.from() を使います。 const itemsArray = [...items]; このように変換してしまえば、itemsArray は純粋な配列となるため、map や filter を自由に使えるようになります。DOM操作を行う際は、「要素の集合を取得したら、それは配列っぽいけど配列じゃないかもしれない」と疑う癖をつけ、必要に応じて配列へ変換するテクニックを持っておくことが重要です。
実践応用:APIからのデータ取得とリスト表示
最後に、配列の知識が実際の開発でどのように役立つかを見てみましょう。現代のWeb開発では、fetch 関数などを使って外部のサーバー(API)からデータを取得し、それを画面に表示する処理が日常的に行われます。
例えば、Qiitaの記事一覧を取得するAPIを叩くと、サーバーからは記事データが入った「JSON形式の配列」が返ってきます。 [{ title: "記事A", ... }, { title: "記事B", ... }, ...]
開発者は、この非同期で取得した配列データに対して、以下の手順で処理を行います。
1. データの取得: fetch と await を使ってデータを取得し、JSONとして解析(パース)します。
2. データの加工: 必要に応じて filter で表示したい記事だけを絞り込んだり、map で必要な情報だけに整形したりします。
3. DOM生成: forEach を使って配列をループし、各データごとに document.createElement("li") でリスト要素を作成します。要素の textContent に記事のタイトルを設定します。
4. 画面への反映: 作成した要素を、画面上の <ul> タグなどに appendChild で追加します。
このように、APIからデータを取得して画面にリスト表示するという、Webアプリで最も一般的な機能の実装は、これまで解説した「配列の基本」「ループ処理」「DOM操作」の組み合わせによって実現されています。配列を理解することは、単なるデータの並べ方を学ぶだけでなく、インターネット上の膨大な情報を自分のアプリケーションに取り込み、活用するための鍵を手に入れることと同義なのです。
