Lodash _.transform() Method

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 6 Examples + 3 Try It
Object utilities

What You’ll Learn

By the end of this tutorial, you’ll use _.transform() to build new objects and aggregates with a mutable accumulator.

01

Core syntax

_.transform(object, iteratee, accumulator)

02

Accumulator

Mutate result object or custom seed.

03

Map + filter

Rename keys, double values, or skip entries.

04

Early exit

Return false to stop iterating.

05

vs reduce

In-place accumulator vs return-each-step.

06

Arrays too

Sum, group, or reshape list data.

What Is _.transform()?

_.transform() is Lodash’s object-friendly alternative to Array.prototype.reduce. You pass a collection, a callback, and an optional accumulator; Lodash walks own enumerable keys and lets you build a new result by mutating that accumulator each step.

💡
One loop, many outcomes

Map keys, filter values, rename properties, or aggregate totals—all in a single pass without chaining multiple Lodash calls.

Use it for data normalization, conditional filtering, grouping, and summing arrays. When every key stays and only values change, _.mapValues() may be simpler; when you need full control, reach for _.transform().

📝 Syntax

The signature takes a collection, iteratee, and optional starting accumulator:

javascript
_.transform(object, [iteratee], [accumulator])

Syntax Rules

  • object — object or array to iterate (own enumerable keys).
  • iteratee(accumulator, value, key, collection) => void; mutate accumulator; return false to break.
  • accumulator — optional seed; defaults to {} for objects.
  • Return value — the final accumulator reference.
  • Source — not modified; only the accumulator changes.
javascript
import transform from "lodash/transform";

const data = { a: 1, b: 2, c: 3 };

const result = transform(data, (acc, value, key) => {
  acc[key.toUpperCase()] = value * 2;
}, {});

// result -> { A: 2, B: 4, C: 6 }

⚡ Quick Reference

TaskCode patternResult
Map + rename keys_.transform(obj, (a,v,k)=>{ a[k.toUpperCase()]=v*2 }, {})New object shape
Filter propertiesif (value > 1) result[key] = valueLike pickBy
Sum an array_.transform(arr, (a,v)=>{ a.total+=v }, { total: 0 })Custom accumulator
Stop earlyreturn false in iterateeBreak loop
Default seed_.transform(obj, fn)Starts as {}
Values only_.mapValues(obj, fn)See _.mapValues()
Pattern
Accumulator

Mutate in place

Source
Read-only

Not mutated

Break
false

Early exit

Default
{}

Object seed

🧰 Parameters

Arguments to _.transform() and how the iteratee builds the result:

object Required

The collection to iterate—typically a plain object or array.

_.transform({ a: 1, b: 2 }, fn, {})
iteratee Optional

(accumulator, value, key, collection). Mutate accumulator each step. Return false to stop.

(result, value, key) => {
  result[key] = value * 2;
}
accumulator Optional

Starting value for the result. Omit for {} on objects; pass { total: 0 } or [] for aggregates.

_.transform(data, fn, {})
return value Output

The same accumulator reference after iteration completes (or breaks early).

const out = _.transform(src, fn, {})

Iteration order follows own enumerable key order. For inherited keys, use _.forIn() or build manually from _.toPairsIn().

Examples Gallery

Practical _.transform() patterns with sample output and interactive Try It Yourself labs.

📚 Getting Started

Build a new object by mutating an accumulator in one pass.

Example 1 — Uppercase keys and double values

Rename each key to uppercase and multiply each value by 2.

javascript
const data = { a: 1, b: 2, c: 3 };

const transformed = _.transform(data, (result, value, key) => {
  result[key.toUpperCase()] = value * 2;
}, {});

console.log(transformed);
// -> { A: 2, B: 4, C: 6 }
Try It Yourself

How It Works

Each callback adds a new key to the empty {} accumulator; the source data object is unchanged.

Example 2 — Filter object properties

Keep only entries where the value is greater than 1—similar to _.pickBy.

javascript
const data = { a: 1, b: 2, c: 3 };

const filtered = _.transform(data, (result, value, key) => {
  if (value > 1) {
    result[key] = value;
  }
}, {});

console.log(filtered);
// -> { b: 2, c: 3 }
Try It Yourself

📈 Practical Patterns

Conditional transforms, array sums, grouping, and comparisons.

Example 3 — Conditional nested transform

Only include nested objects whose value property is greater than 1.

javascript
const data = {
  a: { value: 1 },
  b: { value: 2 },
  c: { value: 3 }
};

const transformed = _.transform(data, (result, obj, key) => {
  if (obj.value > 1) {
    result[key.toUpperCase()] = obj.value * 2;
  }
}, {});

console.log(transformed);
// -> { B: 4, C: 6 }

Example 4 — Sum an array

Use a custom accumulator object to total numeric array elements.

javascript
const data = [1, 2, 3];

const sum = _.transform(data, (result, value) => {
  result.total += value;
}, { total: 0 }).total;

console.log(sum);
// -> 6
Try It Yourself

Example 5 — Group items by category

Build an object of arrays keyed by category name.

javascript
const items = [
  { category: "fruit", name: "apple" },
  { category: "fruit", name: "banana" },
  { category: "veg", name: "carrot" }
];

const grouped = _.transform(items, (result, item) => {
  const cat = item.category;
  (result[cat] || (result[cat] = [])).push(item.name);
}, {});

console.log(grouped);
// -> { fruit: ["apple", "banana"], veg: ["carrot"] }

🚀 Beyond the Basics

When transform fits better than reduce or mapValues.

Example 6 — _.transform() vs _.reduce()

Both can sum values; transform mutates an accumulator, reduce returns each step.

javascript
const data = { a: 1, b: 2, c: 3 };

const viaTransform = _.transform(data, (acc, v) => {
  acc.sum += v;
}, { sum: 0 }).sum;

const viaReduce = _.reduce(data, (acc, v) => acc + v, 0);

console.log(viaTransform, viaReduce);
// -> 6 6

🧠 How _.transform() Works

1

Initialize accumulator

Lodash uses your seed or creates a fresh {} for object input.

Setup
2

Iterate collection

Each own enumerable key invokes the iteratee with accumulator, value, key, and collection.

Loop
3

Mutate or break

You update the accumulator in place. Return false to stop early.

Build
=

Result ready

The final accumulator is returned; the source collection is unchanged.

📝 Notes

  • _.transform() does not mutate the source object or array—only the accumulator.
  • Omit the accumulator to start with an empty object {} for object inputs.
  • Return false from the iteratee to stop iteration early.
  • Works on arrays too—pass a custom seed like { total: 0 } or [].
  • For value-only mapping with the same keys, _.mapValues() is often clearer.
  • Iteration covers own enumerable keys only (not inherited prototype properties).

Conclusion

_.transform() gives you one flexible loop to map, filter, rename, and aggregate object or array data into a new accumulator. Pair it with a clear seed value and mutate the accumulator inside the callback.

When you only need to change values in place, try _.mapValues(). When you only need conditional filtering, _.pickBy() may suffice. Next in the series: _.unset() for removing nested paths.

💡 Best Practices

✅ Do

  • Pass an explicit accumulator when you need arrays or numeric totals
  • Mutate the accumulator inside the iteratee—that is the intended pattern
  • Return false to stop early when you have enough data
  • Use _.mapValues() when keys stay the same and only values change
  • Keep iteratee logic small; extract helpers for complex nested transforms

❌ Don’t

  • Expect the iteratee return value to become the next accumulator (use _.reduce() instead)
  • Forget to initialize numeric fields like { total: 0 } before summing
  • Mutate the source object inside the callback—build a separate accumulator
  • Reach for _.transform() when _.pickBy() or _.mapValues() already fits
  • Assume inherited prototype keys are included—iteration is own enumerable only

Key Takeaways

Knowledge Unlocked

Five things to remember about _.transform()

Use these when one pass should map, filter, and aggregate.

5
Core concepts
🔄 02

One pass

Map + filter.

Pattern
🔀 03

vs reduce

Return vs mutate.

Compare
⏹️ 04

Early exit

Return false.

Tip
📦 05

Source safe

Read-only input.

Note

❓ Frequently Asked Questions

_.transform() iterates over an object or array and builds an accumulator by running a callback on each element. You typically mutate the accumulator inside the callback and receive it back at the end.
Both fold a collection into one value. _.reduce() expects the iteratee to return the next accumulator each step. _.transform() expects you to mutate the accumulator in place; returning false stops iteration early.
No. The source collection is read-only. You choose whether to mutate the accumulator object or array you pass in (or the default empty object Lodash creates).
If you omit the accumulator, Lodash starts with an empty object {} for object inputs. For arrays, pass your own accumulator explicitly (for example [] or { total: 0 }).
Yes. Only copy keys into the accumulator when your condition passes—similar to _.pickBy() but with full control in one loop.
Use _.mapValues() when every key is kept and only values change. Use _.transform() when keys may be renamed, dropped, or when you need array-style aggregation.
Did you know?

_.transform() is the Lodash method behind many “map and filter in one loop” recipes. Unlike Array.prototype.reduce(), you mutate the accumulator instead of returning it each step—and returning false breaks out early, which plain reduce does not offer out of the box.

Practice _.transform() in the Live Editor

Uppercase keys, filter properties, and sum arrays with a mutable accumulator.

Open Try It editor →

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.

6 people found this page helpful