はじめに
システム開発において、データの集計やグループ化で Map を使う機会は非常に多いですよね。
これまでは皆さん、キーが存在しない場合の初期化処理を if 文や has メソッドを使って書いていたと思います。慣れればどうということはないのですが、毎回同じような分岐処理を書くことに、密かに「もっと簡単に書けないかな」と感じていた人もいるのではないでしょうか。
しかし、先日(2026/05/05)リリースされた Node.js 26 正式版 にて、Mapの新メソッド「getOrInsert」がデフォルトで有効になりました。
先行してChromium系ブラウザでも対応しているので、これでより直感的にMapを操作できるようになります。
今までの Map 初期化処理、何がイケてなかったか
これまで Map で「値がなければ初期化して取得する」という処理(いわゆるUpsert的な動き)をするには、以下のステップが必要でした。
-
存在チェック:
map.has(key)を呼ぶ -
初期値のセット: 無ければ
map.set(key, initialValue) -
値の取得: 改めて
map.get(key)を呼ぶ
これだと、同じキーに対して何度も参照が発生してしまいますし、何よりコードが冗長です。
これらを一行で書けるようにしたのが getOrInsert です。
まとめるとこんな感じ
| 処理 | 従来 | getOrInsert |
|---|---|---|
| 存在チェック | 必要 | 不要 |
| 初期化 | 必要 | 不要(自動) |
| 値の取得 | 必要 | 不要(自動) |
| コード量 | 多い | 少ない |
ブラウザでの検証
今回は最新のブラウザ(Chrome バージョン 148.0.7778.168)のコンソールで、その挙動を確認してみます。
実際にコードで比較
データの集計処理(配列への追加)
自分が通ったラーメン屋の「訪問ログ」を、お店ごとに配列で管理するケースを想定してみます。通えば通うほど、そのお店の配列にデータが蓄積されていくイメージです。
const ramenLog = new Map();
// 【これまでの書き方】
// キーがあるか確認して、なければ空配列をセットして...と3行くらい必要
if (!ramenLog.has("つけ麺屋 やすべえ")) {
ramenLog.set("つけ麺屋 やすべえ", []);
}
ramenLog.get("つけ麺屋 やすべえ").push("2026-05-01: 辛味つけ麺");
// 【getOrInsert】
// 「なければセットして、その値を返す」が1行で完結!
// 2回目以降の訪問でも、既存の配列がそのまま返ってくるのでスムーズにpushできます
ramenLog.getOrInsert("蒙古タンメン中本", []).push("2026-05-10: 北極ラーメン");
ramenLog.getOrInsert("蒙古タンメン中本", []).push("2026-05-15: 五目蒙古タンメン");
console.log(ramenLog);
Map(2) {'つけ麺屋 やすべえ' => Array(1), '蒙古タンメン中本' => Array(2)}
▶ [[Entries]]
▶ 0: {"つけ麺屋 やすべえ" => Array(1)}
key: "つけ麺屋 やすべえ"
value: ["2026-05-01: 辛味つけ麺"]
▶ 1: {"蒙古タンメン中本" => Array(2)}
key: "蒙古タンメン中本"
value: ["2026-05-10: 北極ラーメン", "2026-05-15: 五目蒙古タンメン"]
size: 2
やっぱりあの3行がないとスッキリしますね!
上記コードのように [](空配列)や {}(オブジェクト)をデフォルト値として渡す場合、すでにキーが存在していても、毎回新しい配列がメモリ上に生成されてしまうという弱点があります。
もしパフォーマンスやメモリ効率が気になる場合は、もう一つの新メソッド getOrInsertComputed を使うのがベストプラクティスらしいです。
// キーがない時だけ、第2引数の関数が実行されて空配列が作られるので無駄がない
ramenLog.getOrInsertComputed("蒙古タンメン中本", () => []).push("2026-05-15: 五目蒙古タンメン");
getOrInsert を触って感じたメリット
私が実際に触ってみて、特にメリットだと感じたのは以下の4点です。
- コードが圧倒的にスッキリする: 3行が1行になる快感があります。
- 二重参照の解消: 内部で効率的に処理されるため、パフォーマンス向上が期待できます。
- 意図が明確: 「初期化して取得したい」という開発者の意図がメソッド名に凝縮されています。
- 標準機能であること: Lodashなどの外部ライブラリに頼らずに、ピュアなJSでこれが書けるのは大きいです。
さいごに
今回は、Node.js 26への標準実装で密かに注目されている Map.prototype.getOrInsert を触ってみました。
ちょっとしたコーディングのストレスを減らしてくれる良いアップデートでした。
皆さんもぜひ、Mapを使う際は「getOrInsert」を思い出してみてください。
(・・・そろそろ人間がコーディングすることもなくなるんでしょうけどね)
良かったらこちらの記事もご覧ください。
参考
Node.js v26.0.0 リリースノート
MDN Web Docs - Map.prototype.getOrInsert()