JavaScriptにおいて、配列の要素数を取得することは、プログラミングの基礎中の基礎と言えます。
しかし、単に length プロパティを参照するだけでは、時に意図しない挙動に遭遇することがあります。
特に、大規模なデータを扱う際や、メモリ効率を意識した開発が必要な現代のJavaScript(2026年時点の環境を含む)においては、lengthプロパティの背後にある仕組みや、疎な配列(Sparse Array)の取り扱い、そして条件付きでのカウント手法を正確に理解しておくことが不可欠です。
本記事では、配列の要素数を操作・取得するためのあらゆる手法と、実務で役立つ注意点を詳しく解説します。
配列の要素数を取得する基本:lengthプロパティ
JavaScriptの配列(Array)には、その要素数を示す length というプロパティが標準で備わっています。
これはメソッドではないため、length() のように呼び出すのではなく、プロパティとしてアクセスします。
lengthプロパティの基本的な使い方
最も一般的な使い方は、配列に含まれる要素の総数を取得することです。
以下のコード例を見てみましょう。
// 配列の宣言
const fruits = ["apple", "banana", "orange", "grape"];
// 要素数の取得
const count = fruits.length;
console.log(`要素数は ${count} です。`);
要素数は 4 です。
この length プロパティは、配列のインデックスの中で最も大きい数値に1を加えた値を返します。
JavaScriptの配列は0オリジン(0から始まる)であるため、最後の要素のインデックスが3であれば、length は4となります。
lengthは「読み取り専用」ではない
JavaScriptの length プロパティが他の言語の同様の機能と大きく異なる点は、値の書き換えが可能であるという点です。
length に値を代入することで、配列のサイズを強制的に変更できます。
const colors = ["red", "blue", "green", "yellow"];
// lengthを2に変更する(要素を切り捨てる)
colors.length = 2;
console.log(colors);
console.log(colors.length);
["red", "blue"]
2
上記のように、元の length より小さい値を代入すると、配列の後方の要素は破棄されます。
逆に、現在の length より大きい値を代入すると、配列は拡張されますが、新しく確保された領域には値が存在しない「空のスロット」が作成されます。
疎な配列(Sparse Array)とlengthの挙動
JavaScriptでは、配列のインデックスが連続していない「疎な配列」を作成することが可能です。
この場合、length プロパティが示す値と、実際に値が格納されている要素の数は一致しません。
「空のスロット」が含まれるケース
例えば、意図的に特定のインデックスに値を代入した場合、その間のインデックスは「empty(空)」の状態になります。
const sparseArray = [];
sparseArray[0] = "A";
sparseArray[10] = "B";
console.log(sparseArray.length);
console.log(sparseArray);
11
["A", empty × 9, "B"]
この結果からわかる通り、length は 11 となります。
しかし、実際に値が存在するのはインデックス0と10の2箇所だけです。
実務において「有効な値が入っている要素数だけを数えたい」場合には、length をそのまま使うことはできません。
undefinedとemptyの違い
ここで注意が必要なのは、「値がundefinedである要素」と「スロット自体が存在しないempty要素」は別物であるという点です。
| 状態 | lengthへの影響 | 反復処理(forEachなど)での扱い |
|---|---|---|
| 値がある状態 | カウントされる | 実行される |
| 値がundefined | カウントされる | 実行される |
| 空のスロット(empty) | カウントされる | スキップされる |
このように、length プロパティは「メモリ上に値があるかどうか」に関わらず、最大インデックスに基づいた数値を返します。
「実際にデータが存在する数」を知りたい場合は、後述する反復処理を用いたカウントが必要です。
条件に一致する要素数をカウントする方法
単なる全体の長さではなく、「特定の条件を満たす要素がいくつあるか」を知りたい場面は多々あります。
ここでは、現代的なJavaScriptでよく使われる手法を紹介します。
filter()メソッドを利用する
最も直感的でコードの可読性が高いのが filter() メソッドと length を組み合わせる方法です。
const numbers = [10, 25, 40, 15, 60, 5];
// 20以上の数値のみをカウント
const countOver20 = numbers.filter(num => num >= 20).length;
console.log(countOver20);
3
この手法は非常に便利ですが、注意点があります。
filter() メソッドは条件に一致する新しい配列をメモリ上に生成するため、配列の要素数が数十万、数百万規模になる場合、メモリ効率が低下する可能性があります。
reduce()メソッドを利用する
メモリ効率を重視し、新しい配列を作成せずにカウントしたい場合は、reduce() メソッドが適しています。
const scores = [80, 45, 92, 60, 30, 75];
// 70点以上の要素数をカウント
const highScoresCount = scores.reduce((accumulator, currentValue) => {
return currentValue >= 70 ? accumulator + 1 : accumulator;
}, 0);
console.log(highScoresCount);
3
reduce() を使えば、一時的な配列を作らずに数値として累積できるため、大規模データに対しても比較的軽量に動作します。
有効な要素のみをカウントする(emptyを除外する)
前述した「疎な配列」において、実際に値が入っている要素数だけをカウントするには、Object.keys() や forEach() を活用します。
これらは空のスロットを無視する特性があります。
const sparseList = ["apple", , "orange", , "grape"]; // 2箇所の空スロット
console.log("lengthの値:", sparseList.length);
// 有効なキーのみを取得してその数をカウント
const actualCount = Object.keys(sparseList).length;
console.log("実際の要素数:", actualCount);
lengthの値: 5
実際の要素数: 3
多次元配列の要素数をカウントする
配列の中にさらに配列が含まれる「多次元配列」の場合、length プロパティだけでは全体の要素数を把握できません。
フラット化してカウントする
2026年現在の環境では、flat() メソッドを使用して多次元配列を1次元に変換してから length を取得するのが一般的です。
const matrix = [
[1, 2, 3],
[4, 5],
[6, 7, 8, 9]
];
// すべての階層をフラットにしてからカウント
const totalElements = matrix.flat(Infinity).length;
console.log(totalElements);
9
flat(Infinity) を指定することで、深さが不明なネストされた配列であっても、すべて平坦化して要素数を正確に算出できます。
2026年における最新のカウント手法:groupByの活用
ECMAScript 2024で標準化され、現在広く普及している Object.groupBy() や Map.groupBy() を使うと、要素数を確認するだけでなく、「カテゴリごとの個数」を効率的に取得できます。
const inventory = [
{ name: "りんご", type: "fruit" },
{ name: "キャベツ", type: "vegetable" },
{ name: "バナナ", type: "fruit" },
{ name: "トマト", type: "vegetable" },
{ name: "オレンジ", type: "fruit" }
];
// タイプごとにグループ化
const grouped = Object.groupBy(inventory, (item) => item.type);
// それぞれの個数を表示
console.log("フルーツの数:", grouped.fruit.length);
console.log("野菜の数:", grouped.vegetable.length);
フルーツの数: 3
野菜の数: 2
特定の属性に基づいた集計を行いたい場合、従来の for 文や filter を繰り返すよりも、groupByを用いてデータ構造を整理してからlengthを参照するほうが現代的なアプローチと言えるでしょう。
配列の要素数に関するパフォーマンスと注意点
JavaScriptエンジンの内部実装(V8など)において、配列の length プロパティへのアクセスは非常に高速です。
これは、配列のサイズが変更されるたびに内部的に length プロパティが更新されているため、計算量は常にO(1)(定数時間)であり、要素数が増えても取得速度は変わりません。
しかし、以下の点には注意が必要です。
1. 巨大な配列の拡張
length プロパティを直接書き換えて巨大な配列を確保しようとすると、メモリ消費が急激に増大する場合があります。
特に、型付き配列(TypedArray)ではなく通常の配列でこれを行うと、パフォーマンスに悪影響を及ぼす可能性があります。
2. 配列のようなオブジェクト(Array-like)
arguments オブジェクトや NodeList などの「配列のようなオブジェクト」も length プロパティを持っていますが、これらは Array.prototype のメソッド(map や filter など)を直接持っていません。
これらをカウントしたり操作したりする場合は、Array.from() を使って本物の配列に変換するか、スプレッド構文 [...] を利用する必要があります。
// NodeListの例
const divs = document.querySelectorAll("div");
console.log(divs.length); // lengthは持っている
// 配列メソッドを使いたい場合
const divArray = [...divs];
const largeDivsCount = divArray.filter(el => el.offsetWidth > 100).length;
まとめ
JavaScriptにおける配列の要素数取得は、単に length プロパティを見るだけというシンプルな側面と、疎な配列や多次元配列といった複雑な側面の両方を持ち合わせています。
本記事のポイントをまとめます。
- lengthプロパティは、最大インデックスに1を加えた値を返す。
- lengthは書き換え可能であり、値を小さくすると配列の要素が削除される。
- 疎な配列では、空のスロットも
lengthに含まれるため、実際の要素数とは異なる場合がある。 - 条件付きのカウントには、可読性の filter()、メモリ効率の reduce() を使い分ける。
- 2026年現在の開発では、Object.groupBy() を用いたカテゴリ別カウントも非常に有効である。
配列はJavaScript開発において最も多用されるデータ構造の一つです。
その基本である要素数の扱いをマスターすることで、バグの少ない、そしてパフォーマンスに優れたコードを記述できるようになります。
プログラムの要件に合わせて、最適な取得・カウント手法を選択してください。
