JavaScript Array flatMap Method: Complete Guide

flatMap() combines map() and flat(1) into a single method. Learn how to map and flatten in one pass with clear examples and practical use cases.

5 min read

flatMap() does two things at once: it runs a mapping function on every element, then flattens the result by one level. It was added in ES2019 and is the cleaner, more efficient way to combine map() and flat().

javascriptjavascript
const phrases = ["hello world", "goodbye moon"];
 
const words = phrases.flatMap(phrase => phrase.split(" "));
 
console.log(words); // ["hello", "world", "goodbye", "moon"]

Without flatMap(), you would need to chain map() and flat() separately to get the same flattened result, running two full passes over the array instead of one:

javascriptjavascript
const wordsOld = phrases.map(phrase => phrase.split(" ")).flat();
// Same result: ["hello", "world", "goodbye", "moon"]

flatMap() does the same thing but reads more naturally and runs slightly faster because it is a single pass.

Syntax and Parameters

flatMap() takes a single callback function and calls it once for every element in the array:

javascriptjavascript
array.flatMap(callback)

The callback receives the same arguments as map(), giving you access to the element, its position, and the full array if needed:

ParameterDescription
elementThe current element being processed
indexThe index of the current element
arrayThe array flatMap() was called on

The callback must return an array. If it returns anything else, flatMap() throws a TypeError.

Removing Elements by Returning an Empty Array

A unique power of flatMap() is filtering elements by returning [] for the ones you want to remove:

javascriptjavascript
const numbers = [1, 2, 3, 4, 5, 6];
 
// Double evens, remove odds -- all in one pass
const doubledEvens = numbers.flatMap(n =>
  n % 2 === 0 ? [n * 2] : []
);
 
console.log(doubledEvens); // [4, 8, 12]

This is cleaner than the two-pass alternative of mapping first and filtering afterward, which needs a second full iteration over the array:

javascriptjavascript
// Two passes with map + filter
const doubledEvensOld = numbers
  .filter(n => n % 2 === 0)
  .map(n => n * 2);

With flatMap(), you decide per element whether to include it and what value to produce, all in one callback.

Adding Multiple Elements Per Input

flatMap() shines when one input element should produce multiple output elements:

javascriptjavascript
const users = [
  { name: "Alice", hobbies: ["reading", "hiking"] },
  { name: "Bob", hobbies: ["gaming", "cooking", "cycling"] }
];
 
const allHobbies = users.flatMap(user => user.hobbies);
 
console.log(allHobbies);
// ["reading", "hiking", "gaming", "cooking", "cycling"]

Replace each user object with their array of hobbies, then flatten. The result is a single list of every hobby across all users.

Duplicating Elements

You can use flatMap() to repeat elements a certain number of times:

javascriptjavascript
const items = ["a", "b"];
 
const duplicated = items.flatMap(item => [item, item, item]);
 
console.log(duplicated); // ["a", "a", "a", "b", "b", "b"]

flatMap() also works well for generating ranges, where the mapping function returns a differently sized array depending on the input value:

javascriptjavascript
const nums = [1, 2, 3];
 
// Each number repeats itself that many times: [1], [2, 2], [3, 3, 3]
const expanded = nums.flatMap(n => Array(n).fill(n));
 
console.log(expanded); // [1, 2, 2, 3, 3, 3]

Splitting and Normalizing Text

A common data processing task is splitting comma-separated strings and trimming whitespace. flatMap() handles this in a single clean step:

javascriptjavascript
const entries = ["apple, banana", "cherry , date", "elderberry, fig"];
 
const allFruits = entries.flatMap(entry =>
  entry.split(",").map(s => s.trim())
);
 
console.log(allFruits);
// ["apple", "banana", "cherry", "date", "elderberry", "fig"]

Each string is split into an array, each piece is trimmed, and flatMap() flattens the intermediate arrays into one clean list of fruit names. Without flatMap(), you would need map() followed by flat() -- two passes instead of one.

flatMap() vs map() + flat()

arr.flatMap(fn)arr.map(fn).flat()
Passes12
Flatten depthAlways 1Configurable (flat(depth))
FilteringReturn [] to skipRequires separate filter()
PerformanceSlightly fasterSlightly slower (two iterations)

Use flatMap() when you need exactly one level of flattening. Use map() + flat(n) when you need deeper flattening.

Common Mistakes

Returning a non-array value. Since flatMap() expects to flatten the callback's return value, giving it a plain number or string instead of an array throws an error:

javascriptjavascript
const nums = [1, 2, 3];
 
const result = nums.flatMap(n => n * 2);
// TypeError: flatMap callback must return an array

The callback must always return an array, even for a single value. Wrapping the value in brackets fixes it and lets flatMap() flatten it back down normally:

javascriptjavascript
// Right: wrap the value in an array
const result = nums.flatMap(n => [n * 2]);
console.log(result); // [2, 4, 6]

Expecting deep flattening. Since flatMap() only removes one level of nesting, arrays nested more than one level deep still need an extra step:

javascriptjavascript
const nested = [[[1, 2]], [[3, 4]]];
 
// flatMap only flattens one level
const result = nested.flatMap(arr => arr);
console.log(result); // [[1, 2], [3, 4]] (still nested arrays!)
 
// For deeper flattening, use flat() with a depth argument
const deep = nested.flatMap(arr => arr).flat();
console.log(deep); // [1, 2, 3, 4]

flatMap() is flat(1), not flat(Infinity). If you need more depth, chain .flat(n) after flatMap().

Now that you understand flatMap(), learn how to select specific elements with filter or combine and transform values with reduce.

Rune AI

Rune AI

Key Insights

  • flatMap() maps each element to an array and flattens the result by one level.
  • It is equivalent to arr.map(fn).flat() but done in a single, more efficient pass.
  • The callback must return an array. Returning a non-array value will cause an error.
  • Returning an empty array [] effectively removes the element from the result.
  • flatMap() only flattens one level. For deeper flattening, use map() + flat(depth).
RunePowered by Rune AI

Frequently Asked Questions

How is flatMap() different from map() followed by flat()?

flatMap() is equivalent to calling map() followed by flat(1), but it is more efficient because it does both in a single pass. However, flatMap() only flattens one level, just like flat(1). If you need deeper flattening, use map() + flat(depth).

Can flatMap() be used to remove empty elements?

Yes. If your mapping function returns an empty array [], flatMap() effectively filters out that element. This is a common pattern for conditionally including or excluding elements.

Does flatMap() work like flatMap in other languages?

Yes. flatMap() is similar to flatMap in Scala, flat_map in Rust, and SelectMany in C#. The concept is the same: apply a function that returns a collection, then flatten the result.

Conclusion

flatMap() is the method you reach for when you need to map each element to an array and then flatten the result. It is cleaner than chaining map() and flat(), and it is slightly more performant. Use it for one-to-many transformations, conditional filtering within a map, and splitting strings into words in a single pass.