Lodash _.mapValues() method
What you’ll learn
- How
_.mapValues(object, [iteratee])rewrites every value while keeping the same keys. - The iteratee signature
(value, key, object)and the four shorthand forms. - How to use the property-name shorthand to pluck a field from each record in one line.
- How
_.mapValuespairs with _.mapKeys() for full object reshaping.
Prerequisites
Comfortable with Lodash iteratee shorthands. _.mapValues is essentially Array.prototype.map for plain objects.
- Values, not keys: use
_.mapKeysif you only want to transform keys. - Pure function: returns a new object; the source is never mutated.
- Own enumerable only: inherited and symbol-keyed properties are skipped.
Overview
_.mapValues iterates the source’s own enumerable string-keyed properties, calls the iteratee with (value, key, object), and stores the return value under the original key. Use it for unit conversion, type coercion, sanitizing fields, plucking nested properties, or computing derived shapes—anywhere you want object-in, object-out.
map for objects
Like Array.prototype.map, but the input and output keep their object shape.
Shorthand pluck
Pass a property name string to extract a field: mapValues(users, "age").
Pure transform
Safe for selectors and memoized helpers—the input is never modified.
Syntax
_.mapValues(object, [iteratee=_.identity]) - object: source to iterate over. Only own enumerable string-keyed properties are visited.
- iteratee (optional): function, property name string,
[path, value], or matcher object. Receives(value, key, object). - Returns: a new object with the same keys and iteratee-produced values.
Transform every value
The most common shape—feed a function, get a new object with the same keys and transformed values.
import mapValues from "lodash/mapValues";
const scores = { a: 1, b: 2, c: 3 };
mapValues(scores, (value) => value * 2);
// -> { a: 2, b: 4, c: 6 }
const fruits = { a: "apple", b: "banana", c: "cherry" };
mapValues(fruits, (value) => value.toUpperCase());
// -> { a: "APPLE", b: "BANANA", c: "CHERRY" }
scores;
// -> { a: 1, b: 2, c: 3 }
// Source is unchanged. Property shorthand: pluck a field
When values are nested objects, pass a property name string to extract that field from each record. The same Lodash shorthand grammar that _.map uses applies here.
import mapValues from "lodash/mapValues";
const employees = {
e1: { name: "John", age: 30, role: "admin" },
e2: { name: "Alice", age: 25, role: "user" },
e3: { name: "Bob", age: 35, role: "user" }
};
mapValues(employees, "name");
// -> { e1: "John", e2: "Alice", e3: "Bob" }
mapValues(employees, "age");
// -> { e1: 30, e2: 25, e3: 35 }
// Matcher shorthand returns booleans:
mapValues(employees, { role: "admin" });
// -> { e1: true, e2: false, e3: false }
// Function form using (value, key, object):
mapValues(employees, (emp) => ({ ...emp, isSenior: emp.age > 30 }));
// -> { e1: { name: "John", age: 30, role: "admin", isSenior: false },
// e2: { name: "Alice", age: 25, role: "user", isSenior: false },
// e3: { name: "Bob", age: 35, role: "user", isSenior: true } } Sanitize fields & convert types
Real-world flow: trim incoming strings, coerce numerics, and use (value, key, object) for per-field logic.
import mapValues from "lodash/mapValues";
const userInput = {
username: " john_doe ",
email: " john@example.com ",
age: "30"
};
mapValues(userInput, (value) =>
typeof value === "string" ? value.trim() : value
);
// -> { username: "john_doe", email: "john@example.com", age: "30" }
// Per-field logic via the (value, key, object) signature:
const sanitizers = {
username: (s) => s.trim().toLowerCase(),
email: (s) => s.trim(),
age: (s) => Number(s)
};
mapValues(userInput, (value, key) => (sanitizers[key] || ((v) => v))(value));
// -> { username: "john_doe", email: "john@example.com", age: 30 }
// age was coerced from "30" to 30. 📋 _.mapValues vs related helpers
| Topic | _.mapValues | _.mapKeys | Array.prototype.map | Native Object.fromEntries |
|---|---|---|---|---|
| Input | Object | Object | Array | Iterable of [k,v] |
| Output | Object (same keys) | Object (transformed keys) | Array | Object |
| Iteratee args | (value, key, object) | (value, key, object) | (value, index, array) | ([key, value]) |
| Shorthand support | Yes | Yes | No (write the map function) | No |
| Mutates input | No | No | No | No |
Use _.mapValues when only values change. Use _.mapKeys when only keys change. For rewriting both at once, reach for Object.fromEntries(Object.entries(obj).map(...)).
Pitfalls to avoid
Returning the same reference shares state
If your iteratee returns the same nested object it received (instead of a copy), the new map shares those nested objects with the source. Later mutations affect both.
Default iteratee just clones
Without an iteratee, _.identity is used—you get a shallow clone of own enumerable values. Almost always pass an explicit iteratee.
Throws bubble up
If your iteratee throws, _.mapValues propagates the error. Wrap the body in try/catch if you need per-value resilience.
Inherited and symbol keys are skipped
Only own enumerable string-keyed properties are processed. Bring symbols or prototype properties forward manually if you need them.
❓ FAQ
Summary
- Purpose: build a new object whose values come from an iteratee while keeping the same keys.
- Remember: the property-name shorthand makes "pluck this field from every record" a one-liner.
- Next: Lodash _.merge(), _.mapKeys(), or the official Lodash docs for _.mapValues.
_.mapValues is the object-shaped Array.prototype.map. Keys are preserved exactly; only values are rewritten. Pair it with _.mapKeys when you need to rewrite both sides at once.
5 people found this page helpful
