DEV Community

Cover image for Inverting an Object in JavaScript: Swap Keys and Values
Daniel Keya
Daniel Keya

Posted on

Inverting an Object in JavaScript: Swap Keys and Values

Ever needed to look something up by value instead of by key? That's exactly what object inversion solves. In this short post we'll break down a clean invert utility that flips an object's keys and values — and explore where this pattern shows up in real code.


The Full Function

export function invert(obj) {
  const result = {};
  for (const [key, value] of Object.entries(obj)) {
    result[value] = key;
  }
  return result;
}
Enter fullscreen mode Exit fullscreen mode

Usage:

console.log(invert({ a: "x", b: "y", c: "z" }));
// → { x: "a", y: "b", z: "c" }
Enter fullscreen mode Exit fullscreen mode

Keys become values. Values become keys. Simple.


How It Works

Step 1 — Create an empty result object

const result = {};
Enter fullscreen mode Exit fullscreen mode

We build the inverted object fresh rather than mutating the original. This keeps the function pure — no side effects, same input always gives same output.


Step 2 — Iterate with Object.entries

for (const [key, value] of Object.entries(obj)) {
Enter fullscreen mode Exit fullscreen mode

Object.entries converts the object into an array of [key, value] pairs. Destructuring them directly in the for...of loop keeps the code clean — no pair[0] / pair[1] indexing needed.

For { a: "x", b: "y", c: "z" } this yields:

["a", "x"]
["b", "y"]
["c", "z"]
Enter fullscreen mode Exit fullscreen mode

Step 3 — Assign with keys and values swapped

result[value] = key;
Enter fullscreen mode Exit fullscreen mode

Each iteration assigns the original value as the new key, and the original key as the new value. That's the entire inversion logic — one line.


Step 4 — Return the result

return result;
Enter fullscreen mode Exit fullscreen mode

The original object is untouched. A brand new inverted object is returned.


Dry Run: { a: "x", b: "y", c: "z" }

Iteration key value result after
1 "a" "x" { x: "a" }
2 "b" "y" { x: "a", y: "b" }
3 "c" "z" { x: "a", y: "b", z: "c" }

Final output: { x: "a", y: "b", z: "c" }


Real-World Use Cases

This pattern comes up more often than you'd think:

Reverse lookup maps — you have a map of country codes to names and need to search by name:

const codes = { US: "United States", KE: "Kenya", DE: "Germany" };
const byName = invert(codes);
// { "United States": "US", "Kenya": "KE", "Germany": "DE" }

byName["Kenya"]; // → "KE"
Enter fullscreen mode Exit fullscreen mode

Decoding encoded data — you encode values on the way out and decode on the way back:

const encode = { admin: "a1", user: "u2", guest: "g3" };
const decode = invert(encode);

decode["u2"]; // → "user"
Enter fullscreen mode Exit fullscreen mode

Swapping label/value pairs in form selects — when an API returns the opposite shape from what your UI expects.


Edge Cases to Know

Duplicate values — last one wins

If two keys share the same value, the second assignment overwrites the first:

invert({ a: "x", b: "x" });
// → { x: "b" }   ← "a" is lost
Enter fullscreen mode Exit fullscreen mode

This is not a bug in the function — it's a fundamental constraint. Object keys must be unique, so if your values aren't unique, inversion is lossy by definition.


Non-string values become strings

Object keys are always strings (or Symbols) in JavaScript. If your values are numbers or booleans, they get coerced when used as keys:

invert({ active: true, count: 42 });
// → { true: "active", 42: "count" }
Enter fullscreen mode Exit fullscreen mode

The values true and 42 become the string keys "true" and "42". Usually harmless, but worth knowing.


Nested objects don't invert recursively

invert only works one level deep. If a value is itself an object, it becomes [object Object] as a key — almost certainly not what you want:

invert({ a: { nested: true } });
// → { "[object Object]": "a" }
Enter fullscreen mode Exit fullscreen mode

For deep inversion you'd need a recursive approach with different logic.


A One-Liner Alternative

If you prefer a functional style without the explicit loop:

const invert = obj =>
  Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
Enter fullscreen mode Exit fullscreen mode

Same result — Object.entries unpacks, .map swaps each pair, Object.fromEntries repacks. The for...of version is easier to read at a glance; this one is more compact for quick use.


Complexity

Time O(n) where n = number of keys
Space O(n) for the new result object

Every key is visited once. A new object of equal size is created.


Wrapping Up

invert is one of those utility functions small enough to fit in a tweet but useful enough to reach for regularly. The pattern — Object.entries to unpack, swap, reassign — is the same one powering mapEntries, filterEntries, and most other object transformation helpers.

Keep it in your utility belt. You'll need it.

If you enjoyed this, feel free to check out more of my work on GitHub 👉 keyadaniel56 — always building something new.

Top comments (0)