概要
JavaScriptで扱うデータは主に以下の2構造に大別される:
-
オブジェクト(連想配列):
{ key: value }
-
配列(順序付きリスト):
[item1, item2, ...]
この二つをどう設計的に使い分け、構造化し、検索性や拡張性を担保するかが、可読性と性能の鍵となる。
1. データ構造の基本的な役割
データ型 | 意味 | 主な用途 |
---|---|---|
配列 | 順序付きの同型コレクション | 一覧表示、順序付きの反復処理 |
オブジェクト | キーと値のペア、順序は保証されない | 個別データのプロパティ管理 |
2. 選定指針:配列 or オブジェクト?
✅ 配列に向いている
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
- 要素の数が可変
- 順序が意味を持つ(表示順、優先順位)
-
map
,filter
,reduce
などで反復処理したい
✅ オブジェクトに向いている
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com'
};
- 固定フィールドの集合体
- 個別のエンティティの属性保持
3. ネスト構造と正規化
❌ 悪い例(ネストが深く、冗長)
const data = {
departments: [
{
name: 'Engineering',
members: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]
}
]
};
→ 検索や更新が煩雑(userIdから探すのが難しい)
✅ 正規化された構造
const departments = {
1: { id: 1, name: 'Engineering', memberIds: [1, 2] }
};
const users = {
1: { id: 1, name: 'Alice' },
2: { id: 2, name: 'Bob' }
};
→ 検索性・更新性・参照性が高くなる
4. IDベースの構造設計:Map的アクセス最適化
const usersById = {
101: { id: 101, name: 'Toto' },
102: { id: 102, name: 'Nana' }
};
const ids = [101, 102];
const userList = ids.map(id => usersById[id]);
- ✅ 配列で順序を保ちつつ
- ✅ オブジェクトで O(1) アクセスを実現
5. “検索性”の高い設計とは?
❌ filterによる都度検索
const user = users.find(u => u.id === 42); // O(n)
→ ✅ 頻繁に検索する場合は Map
構造へ
✅ Mapやオブジェクトで即座に取得
const userMap = new Map([
[42, { id: 42, name: 'Alice' }]
]);
const user = userMap.get(42); // O(1)
6. 実践ユースケース:APIレスポンス整形
❌ APIからの生データ
[
{ id: 1, team: 'A', name: 'Alice' },
{ id: 2, team: 'A', name: 'Bob' },
{ id: 3, team: 'B', name: 'Nana' }
]
✅ 正規化 + 紐付け構造
const teams = {
A: { name: 'A', memberIds: [1, 2] },
B: { name: 'B', memberIds: [3] }
};
const users = {
1: { id: 1, name: 'Alice' },
2: { id: 2, name: 'Bob' },
3: { id: 3, name: 'Nana' }
};
設計判断フロー
① 順序付きのコレクション? → 配列
② 固定属性の集合体? → オブジェクト
③ よく検索する? → オブジェクト or Map に展開
④ 関連エンティティがある? → IDで紐付けて分離設計
⑤ APIレスポンスを使う? → normalizeしてから保持
結語
構造化とは“設計された使いやすさ”である。
ただデータを持つのではなく、アクセス・参照・変更を設計することが本質である。
- ネストを浅く、意味を明確に
- 配列は順序・オブジェクトは参照
- 検索するならMap的構造へ
- 関係性はIDで結び、正規化する
扱いやすいデータは、コードの読みやすさと信頼性を高める。構造とは、操作性そのものである。