ID で検索とは何か
「ID で検索」は、配列やオブジェクトの中から“特定の一件”を高速・安全に取り出す実務の基本パターンです。ここが重要です:配列から毎回探すのは線形検索で遅くなりがち。頻繁に検索するなら辞書(オブジェクト/Map)に変換しておき、ID→レコードを即座に取り出す設計にすると安定します。
// 配列で単発検索(O(n))
const user = users.find(u => u.id === targetId);
// 辞書で検索(O(1))
const user = usersById[targetId]; // もしくは map.get(targetId)
JavaScript配列から ID で探す(単発検索の定番)
基本:find / findIndex
const users = [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }];
const targetId = 2;
const user = users.find(u => u.id === targetId); // レコード(見つからなければ undefined)
const index = users.findIndex(u => u.id === targetId); // 位置(見つからなければ -1)
JavaScript- 使い分け: レコードが欲しいときは find。位置が欲しい(更新・削除)ときは findIndex。
- 安全策: 比較は厳密等価(===)で型ブレを防ぐ。文字列IDなら
String(u.id) === String(targetId)のように揃える。
その場で非破壊更新(ID マッチだけ置換)
function updateById(items, id, patch) {
return items.map(it => it.id === id ? { ...it, ...patch } : it);
}
JavaScript- ポイント: map で“該当IDだけ新インスタンス”に置換。イミュータブルで差分検知が安定。
辞書(オブジェクト/Map)にして O(1) で検索
オブジェクトを辞書化(Record パターン)
const usersById = Object.fromEntries(users.map(u => [u.id, u]));
// 取得
const user = usersById[targetId];
JavaScript- 利点: シンプルで速い、JSON シリアライズもしやすい。
- 注意: キーは文字列化されるため、数値IDでも
"2"として格納される。型を揃える習慣を持つ。
Map を使う(キー型を維持、メソッドが豊富)
const usersMap = new Map(users.map(u => [u.id, u]));
const user = usersMap.get(targetId);
JavaScript- 利点: キー型を保持(数値/オブジェクトキー)、サイズや反復が便利(.size, .keys())。
- 注意: JSON 化は直接できない。必要なら
Array.from(map)で配列化して保存。
実務の分岐
- 少量・保存優先: オブジェクト辞書。
- 大量・キー多様・操作豊富: Map。
正規化(entities)で複数テーブルを整える
正規化の骨子(ID 指向に再設計)
const entities = {
users: { 1: { id: 1, name: "Alice" }, 2: { id: 2, name: "Bob" } },
posts: { 10: { id: 10, authorId: 1, commentIds: [100] } },
comments: { 100: { id: 100, authorId: 2, text: "Hi" } }
};
// 検索
const user = entities.users[1];
const post = entities.posts[10];
JavaScript- メリット: 一元更新(users[1] を更新すれば全参照が最新)、部分更新が高速、関係が明確。
- 表示時の復元: ID を辿って“見せる形”にデノーマライズして使う。
まとめ検索・一括取得・存在チェック
複数 ID をまとめて取得
function pickMany(dict, ids) {
return ids.map(id => dict[id]).filter(x => x != null);
}
const users = pickMany(usersById, [1, 2, 99]); // 99 は除外
JavaScript存在チェックと既定値
const exists = Object.hasOwn(usersById, targetId); // 自前キーの判定
const user = usersById[targetId] ?? { id: targetId, name: "(unknown)" };
JavaScript部分一致の検索(辞書+インデックスの併用)
- ラベル検索: 事前に name→id のインデックスを組むと速い。
const indexByName = Object.fromEntries(users.map(u => [u.name.toLowerCase(), u.id]));
const id = indexByName["alice"];
const user = id != null ? usersById[id] : undefined;
JavaScript更新・削除の実務パターン(ID 基軸で安全に)
辞書の非破壊更新
function upsert(dict, record) {
return { ...dict, [record.id]: { ...(dict[record.id] ?? {}), ...record } };
}
function remove(dict, id) {
const { [id]: _, ...rest } = dict;
return rest;
}
JavaScript- ポイント: 追加/更新は上書き(アップサート)、削除は分割代入でキー除去。すべて非破壊。
配列+辞書のハイブリッド
function upsertList(list, record) {
const i = list.findIndex(x => x.id === record.id);
if (i === -1) return [...list, record];
return list.map((x, idx) => (idx === i ? { ...x, ...record } : x));
}
JavaScript- ポイント: “表示順(配列)”と“即時検索(辞書)”を両立する場合に併用。
重要な注意点(ここが核心)
ID の型と一意性
- 型の統一: 指針: 受け取り次第
String(id)などで正規化して保管。比較は常に厳密等価(===)。 - 一意性の保証: 指針: サーバー発行IDや UUID を使用。インデックス番号は避ける(並び替えで破綻)。
欠損・安全なアクセス
- 欠損対策: 指針:
dict[id] ?? defaultで既定値。配列探索はfind(...) ?? null。 - ネスト: 指針:
entities.post?.[id]?.commentIds ?? []のように?.+??を組み合わせる。
性能と同期
- O(n) の限界: 指針: 検索が多い・データが増えるなら辞書化(O(1))に切り替える。
- 同期の一貫性: 指針: 正規化側(辞書)を唯一の更新源にし、表示は再構成。二重更新を避ける。
実践レシピ(すぐ使えるコード)
辞書を作るユーティリティ
const toDict = (list, key = "id") =>
Object.fromEntries(list.map(x => [x[key], x]));
JavaScript一括検索+欠損補完
function lookupAll(dict, ids, filler = id => ({ id, missing: true })) {
return ids.map(id => dict[id] ?? filler(id));
}
JavaScript参照整合付き追加(関係を更新)
function addComment(entities, comment) {
const comments = { ...entities.comments, [comment.id]: comment };
const post = entities.posts[comment.postId];
const nextPost = { ...post, commentIds: [...post.commentIds, comment.id] };
return {
...entities,
comments,
posts: { ...entities.posts, [post.id]: nextPost }
};
}
JavaScriptまとめ
ID で検索は「単発なら find、頻繁なら辞書化」という切り替えが核心です。辞書(オブジェクト/Map)にして O(1) 検索へ、正規化(entities)で“一元更新”できる構造を作る。更新・削除は非破壊に、関係データは両側の整合を保つ。ID の型と一意性を徹底し、欠損には ?.+?? で安全化。これだけ押さえれば、初心者でも大規模データを意図どおりに素早く、安全に検索・更新できます。

