---
title: "Map.getOrInsert: one less if between you and the job offer · Ihab Khattab"
description: "Half of LeetCode is the same ritual: check if the key exists, add it if it doesn't, then use it. Map.prototype.getOrInsert() performs the ritual for you, so…"
url: "https://ihabkhattab.com/til/map-get-or-insert/"
---

# Map.getOrInsert: one less if between you and the job offer

Nov 5, 2026 · [Also on X](https://x.com/HO_BA/status/2118323225646264545)

Half of LeetCode is the same ritual: check if the key exists, add it if it doesn’t, then use it. `Map.prototype.getOrInsert()` performs the ritual for you, so you can retire the `if` you’ve typed 4,000 times.

Take [Group Anagrams](https://leetcode.com/problems/group-anagrams/): put words made of the same letters in one group. Sort a word’s letters and you get its group’s key: `eat` and `tea` both become `aet`. Each key holds a list of its words.

_groupAnagrams.js_

```js
  function groupAnagrams(words) {
    const groups = new Map();
    for (const word of words) {
      const key = [...word].sort().join("");
-     if (!groups.has(key)) {
-       groups.set(key, []);
-     }
-     groups.get(key).push(word);
+     groups.getOrInsert(key, []).push(word);
    }
    return [...groups.values()];
  }
```

Same answer, with time left to panic about the follow-up question.

Yes, `Map.groupBy` solves this one too. Let me have this.

`getOrInsertComputed()` takes a function instead of a value and only calls it when the key is missing. With `getOrInsert()`, the default gets evaluated first, every time, hit or miss. So:

- Cheap default like `[]` or `new Set()`: `getOrInsert()`.
- Expensive default, or one with side effects: `getOrInsertComputed()`.

Pick wrong and you get a memo that remembers everything and saves nothing. Here’s Fibonacci, with each version’s own `Map`:

```js
// 2,692,537 calls for n = 30. Both recursive calls run before the map is even asked.
const slow = (n) =>
  n < 2 ? n : slowMemo.getOrInsert(n, slow(n - 1) + slow(n - 2));

// 59 calls. The callback only runs on a miss.
const fast = (n) =>
  n < 2 ? n : fastMemo.getOrInsertComputed(n, () => fast(n - 1) + fast(n - 2));
```

Both have been [Baseline](https://web-platform-dx.github.io/web-features-explorer/features/getorinsert) since February 2026: Chrome and Edge 145, Firefox 144, Safari 26.2. Node 26 has them, Node 24 doesn’t. For anything older, use a polyfill like [core-js](https://core-js.io/docs/features/ecmascript/collections#h-map). `WeakMap` gets both too.

The catch: [LeetCode runs Node 22.14](https://support.leetcode.com/hc/en-us/articles/360011833974-What-are-the-environments-for-the-programming-languages), where this throws a `TypeError`. The `if` keeps its job a little longer.

Outside LeetCode, [Sébastien Lorber](https://x.com/sebastienlorber/status/2118283344144466408) uses it to lazily fill a cache:

```js
return cache.getOrInsertComputed(options, () =>
  createProcessors({ options }),
);
```

More: [MDN: getOrInsert()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/getOrInsert) · [MDN: getOrInsertComputed()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/getOrInsertComputed)

[← All TILs](https://ihabkhattab.com/til/)
