Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 2

Transforming and Filtering Arrays with map() and filter()

Recommended resources

Hello! Welcome back to our course on mastering modern JavaScript.

In the last lesson, we introduced the fundamental difference between imperative programming (like for loops) and the more modern, declarative style offered by array methods. You got a first look at map(), filter(), and forEach(), and learned how they express what you want to do rather than detailing how to do it.

Today, we'll dive deeper into two of the most essential array methods: map() and filter(). This lesson is all about building proficiency. By the end, you'll be comfortable using map() to transform data from one shape to another and filter() to precisely select the data you need. These are core skills you'll use constantly, especially when handling data from a backend API like your Laravel applications.

1. map(): The Transformation Specialist

As we touched on previously, map() creates a new array by applying a function to every element of the original array. It's your go-to method for transforming data. The key things to remember are:

  1. It always returns a new array.
  2. The new array always has the same length as the original one.
  3. It does not change the original array (this is called immutability).

To get a solid foundation with clear code examples, let's start with a reading.

map, reduce, filter - 33 JavaScript Concepts

The article 'map, reduce, filter' on 33jsconcepts.com provides an excellent, detailed overview of map(). It's a great reference you can come back to.

Please read the section titled 'map() — Transform Every Element'. Pay close attention to the subsections on 'Extracting Properties from Objects' and 'Transforming Object Shapes', as these are extremely common use cases.

Common map() Use Cases

Let's solidify the patterns from the reading with some examples. Imagine you've fetched this user data from your API:

const users = [
  { id: 1, firstName: 'Grace', lastName: 'Hopper', role: 'developer' },
  { id: 2, firstName: 'Ada', lastName: 'Lovelace', role: 'developer' },
  { id: 3, firstName: 'Margaret', lastName: 'Hamilton', role: 'manager' }
];

1. Extracting a single property:

This is useful when you just need a simple list of values from your objects.

// Get an array of just the user's first names
const firstNames = users.map(user => user.firstName);
console.log(firstNames);
// Output: ['Grace', 'Ada', 'Margaret']

2. Reshaping objects:

This is powerful for preparing data for display. You can create a new, simpler object shape for your frontend components.

// Create a new array of objects with a 'fullName' and 'role'
const displayUsers = users.map(user => {
  return {
    fullName: `${user.firstName} ${user.lastName}`,
    role: user.role
  };
});

console.log(displayUsers);
// Output: 
// [
//   { fullName: 'Grace Hopper', role: 'developer' },
//   { fullName: 'Ada Lovelace', role: 'developer' },
//   { fullName: 'Margaret Hamilton', role: 'manager' }
// ]

Important Note on Immutability: When transforming objects, it's crucial not to accidentally change the original data. The article map, reduce, filter touches on this in a subsection called "Mutating Original Objects". To update an object's property while respecting immutability, you should create a new object. The modern way to do this is with the spread (...) operator.

// Give all developers a 'senior' title
const seniorDevs = users.map(user => {
  if (user.role === 'developer') {
    // Return a NEW object with the 'role' property updated
    return { ...user, role: 'senior developer' };
  }
  // If not a developer, return the original object unchanged
  return user;
});

This ensures the original users array and its objects remain untouched.


2. filter(): The Data Selector

While map() transforms every element, filter() is used to select a subset of elements. It creates a new, often smaller, array containing only the elements that cause the function you provide to return true.

The following video gives a great visual explanation of filter() in a practical e-commerce context.

How to use map() filter() reduce() | JavaScript Array Methods Tutorial

This video from Coding2GO provides a concise and practical look at the filter() method, using a product list as an example.

Watch the segment from 04:35 to 07:12. Notice how filter() is used to select items based on a condition and how multiple conditions can be combined.

Common filter() Use Cases

Using our users array again:

const users = [
  { id: 1, name: 'Grace', age: 85, role: 'developer' },
  { id: 2, name: 'Ada', age: 36, role: 'developer' },
  { id: 3, name: 'Margaret', age: 85, role: 'manager' }
];

1. Filtering by a property value:

// Get all users who are developers
const developers = users.filter(user => user.role === 'developer');
console.log(developers);
// Output:
// [
//   { id: 1, name: 'Grace', age: 85, role: 'developer' },
//   { id: 2, name: 'Ada', age: 36, role: 'developer' }
// ]

2. Filtering with multiple conditions:

As you saw in the video, you can easily combine conditions using logical operators like && (and) and || (or).

// Get all developers who are older than 40
const seniorDevelopers = users.filter(user => user.role === 'developer' && user.age > 40);
console.log(seniorDevelopers);
// Output:
// [
//   { id: 1, name: 'Grace', age: 85, role: 'developer' }
// ]

3. Method Chaining: The Real Power

The true elegance of these methods shines when you chain them together. Since filter() returns a new array, you can immediately call map() on that result. This creates a clean, readable data-processing pipeline.

This is the most common pattern you'll see: first filter down your dataset, then map the results into the shape you need.

Let's watch a clear demonstration of this technique.

map, filter & reduce 🙏 Namaste JavaScript Ep. 19 🔥

In this clip from the 'Namaste JavaScript' series, Akshay Saini demonstrates how to chain filter() and map() to solve a multi-step problem.

Watch the segment from 32:15 to 35:39. Focus on how he first filters the array to get a smaller list and then maps over that result to extract the specific data he needs.

As the video shows, a common task like "Get the first names of all people younger than 30" becomes beautifully simple:

const output = users
  .filter(user => user.age < 40)  // Step 1: Get users younger than 40 -> [ {Ada}, ... ]
  .map(user => user.name);        // Step 2: Get the names from that filtered list -> [ 'Ada' ]

console.log(output); // ['Ada']

4. Your Turn: Practice Exercise

Let's put this all together. Here is an array representing products in an e-commerce store.

const products = [
  { id: 'p01', name: 'Wireless Mouse', category: 'electronics', price: 25.00, inStock: true },
  { id: 'p02', name: 'Bluetooth Keyboard', category: 'electronics', price: 80.00, inStock: false },
  { id: 'p03', name: '10ft USB-C Cable', category: 'electronics', price: 15.50, inStock: true },
  { id: 'p04', name: 'Ergonomic Chair', category: 'furniture', price: 350.00, inStock: true },
  { id: 'p05', name: 'LED Desk Lamp', category: 'home goods', price: 45.00, inStock: true },
  { id: 'p06', name: 'Webcam HD', category: 'electronics', price: 120.00, inStock: false },
];

Your Task:
Write a single, chained statement that produces a new array of strings. Each string should contain the name and price of all in-stock electronics products, formatted like this: "Wireless Mouse - $25.00".

Hint: You'll need to filter() first, and then map() the results. Your filter callback will need to check two conditions.

Try to solve it yourself before looking at the solution!

Click to see the solution
const productDisplayList = products
  // Step 1: Filter the array to get only the items that match our criteria
  .filter(product => product.category === 'electronics' && product.inStock === true)
  
  // Step 2: Map over the filtered results to create the formatted strings
  .map(product => `${product.name} - $${product.price.toFixed(2)}`);

console.log(productDisplayList);
// Expected Output:
// [
//   "Wireless Mouse - $25.00",
//   "10ft USB-C Cable - $15.50"
// ]

(Note: toFixed(2) is used here to ensure the price is always formatted with two decimal places, e.g., $25.00 instead of $25)


Conclusion

Great work! You've now taken a deep dive into map() and filter(), the two workhorses of array manipulation in JavaScript.

Key Takeaways:

  • map() is for transforming data. Use it when you need to change every item in an array into something else (e.g., extracting a property, reshaping an object).
  • filter() is for selecting data. Use it when you need to pick a subset of items from an array that meets specific criteria.
  • Method chaining (.filter().map()) is an extremely powerful and common pattern for processing data in a clean, readable pipeline.

Mastering this declarative, pipeline-based approach to data is a huge step toward writing professional, modern JavaScript.

In our next lesson, we'll introduce the final core array method from this family: reduce(), which is used to aggregate an entire array into a single value.