Lodash _.invertBy() method

Beginner
⏱️ 7 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

What you’ll learn

  • How _.invertBy(object, [iteratee]) turns a source object into { bucketKey: [...sourceKeys] }.
  • How the optional iteratee derives the bucket key from each value.
  • When _.invertBy wins over _.invert()—every duplicate value is preserved as an array entry.
  • Common shorthand forms: function, property name, [path, value], and matcher object.

Prerequisites

You should be comfortable with iteratee shorthands and know that _.invert loses keys when values collide. _.invertBy is the duplicate-safe variant.

  • Always arrays: each bucket is an array, even when only one source key landed in it.
  • Iteratee shorthands: function, string, [path, value], and matcher object are all valid.
  • Pure function: returns a new object; the input is never mutated.

Overview

_.invertBy walks the source object’s own enumerable string-keyed properties. For each entry it asks the iteratee “which bucket does this value belong to?” and appends the source key to that bucket. The result is a tidy { bucketKey: [keys] } structure—perfect for grouping and reverse-lookup.

Duplicate-safe

Repeated values are collected into the same bucket. Nothing is overwritten.

Iteratee-driven buckets

Group by a property, a formula, or any function you like—not just the raw value.

Pure transform

A new object every time. Safe to call from selectors and memoized helpers.

Syntax

javascript
_.invertBy(object, [iteratee=_.identity])
  • object: any object to invert. Only own enumerable string-keyed properties are walked.
  • iteratee (optional): function, property name string, [path, value], or matcher object. It receives the source value and returns the bucket key. Defaults to the value itself.
  • Returns: a new object of buckets, each one an array of source keys.
1

Group source keys by their value

Without an iteratee, _.invertBy simply collects every source key under its stringified value.

javascript
import invertBy from "lodash/invertBy";

const items = {
  apple: "fruit",
  banana: "fruit",
  carrot: "vegetable"
};

invertBy(items);
// -> { fruit: ["apple", "banana"], vegetable: ["carrot"] }

const scores = { A: 1, B: 2, C: 1, D: 3 };
invertBy(scores);
// -> { "1": ["A", "C"], "2": ["B"], "3": ["D"] }
Try it Yourself
2

Custom buckets with an iteratee

Pass a function to derive the bucket key. This is the workflow for grouping by length, range, category, status flags, and so on.

javascript
import invertBy from "lodash/invertBy";

const fruits = {
  1: "apple",
  2: "banana",
  3: "orange"
};

invertBy(fruits, (name) => name.length);
// -> { "5": ["1"], "6": ["2", "3"] }
//    apple -> 5; banana, orange -> 6

const orders = {
  o1: 42,
  o2: 7,
  o3: 105,
  o4: 23
};

invertBy(orders, (amount) => amount >= 50 ? "large" : "small");
// -> { small: ["o1", "o2", "o4"], large: ["o3"] }
Try it Yourself
3

Iteratee shorthands for nested values

When values are objects, pass a property name string instead of writing a function. The four classic Lodash shorthands all apply.

javascript
import invertBy from "lodash/invertBy";

const users = {
  alice:   { id: 1, age: 25, role: "admin" },
  bob:     { id: 2, age: 30, role: "user"  },
  charlie: { id: 3, age: 25, role: "user"  },
  dana:    { id: 4, age: 30, role: "admin" }
};

invertBy(users, "age");
// -> { "25": ["alice", "charlie"], "30": ["bob", "dana"] }

invertBy(users, "role");
// -> { admin: ["alice", "dana"], user: ["bob", "charlie"] }

invertBy(users, { role: "admin" });
// -> { true: ["alice", "dana"], false: ["bob", "charlie"] }
//    Matcher shorthand returns booleans, which become string keys.
Try it Yourself

📋 _.invertBy vs related helpers

Topic_.invertBy_.invert_.groupBy
InputObjectObjectCollection (array or object)
Bucket valueArray of source keysOne source key (last wins)Array of source items
Duplicates handledYesNo, overwrittenYes
Iteratee shorthandsYesNoYes
Mutates inputNoNoNo

Use _.invertBy when you want to remember which keys ended up in each bucket. Use _.groupBy when you want the original values in each bucket. Use _.invert only when values are guaranteed unique.

Pitfalls to avoid

Types

Bucket keys are always strings

Numbers, booleans, and other primitives are stringified when they become object keys. TypeScript will see them as string keys after the inversion.

Objects

Returning objects from the iteratee collapses buckets

If your iteratee returns a non-primitive, all results stringify to "[object Object]" and merge into one bucket. Return a primitive identifier instead.

Iteration

Bucket array order follows source iteration

The array of source keys reflects Lodash key iteration order. If you need lexicographic order, sort the array yourself.

Coverage

Own enumerable string keys only

Symbol-keyed and inherited properties are ignored. Reach for a manual loop if you need them.

❓ FAQ

A new object where each key is a value (or iteratee-derived bucket) from the source, and each value is an array of source keys that mapped to it. Duplicate source values are preserved as multiple entries in the bucket.
_.invert returns flat { value: key } pairs and silently drops keys when values collide. _.invertBy collects every source key into an array per bucket, so nothing is lost when values repeat.
No. Without an iteratee, the original value itself becomes the bucket key. Pass an iteratee when you want to bucket by a derived property, such as object age, string length, or category.
Yes. Like other Lodash collection methods, the iteratee can be a function, a string property name (e.g. "age"), a [path, value] array, or an object matcher.
No. It always returns a new object. The source is untouched.
Yes. Object keys are strings (or symbols) in JavaScript, so the iteratee result is stringified when it becomes a key. Be careful with object-typed iteratee returns—they will all collapse to "[object Object]".

Summary

Did you know?

_.invertBy always produces buckets (arrays) on the right-hand side, even when a value is unique. Use _.invert if you specifically want flat { value: key } pairs and you know every value is one-of-a-kind.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful