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;
}
Usage:
console.log(invert({ a: "x", b: "y", c: "z" }));
// → { x: "a", y: "b", z: "c" }
Keys become values. Values become keys. Simple.
How It Works
Step 1 — Create an empty result object
const result = {};
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)) {
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"]
Step 3 — Assign with keys and values swapped
result[value] = key;
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;
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"
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"
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
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" }
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" }
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]));
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)