JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
43: Array Methods: map, filter, reduce
A few years ago, I was reviewing a pull request from a junior dev who was building a shopping cart feature. He had written this massive 40-line block of code involving three different for loops and several temporary "accumulator" variables just to calculate a total price after applying a discount to specific categories. It worked, but it was brittle. If someone changed a variable name or shifted the loop logic, the whole thing would collapse like a house of cards. I remember telling him, "You're treating JavaScript like it's C from 1985. Let's use the tools the language actually gives us."
That's where map, filter, and reduce come in. These aren't just "shorter ways" to write loops; they are functional programming tools that allow you to describe what you want to happen to your data, rather than how to move a pointer through an array. They return new arrays or values instead of mutating the original data, which is a lifesaver when you're debugging complex state in a real application.
Turning Raw Data into Display-Ready Lists
Whenever you find yourself creating an empty array and pushing items into it inside a loop, you should probably be using map. It takes an existing array and transforms every single element into something else, returning a brand new array of the exact same length.
Let's say you have a list of product objects from an API, but you only need an array of their formatted price tags for the UI:
const products = [
{ name: 'Mechanical Keyboard', price: 120 },
{ name: 'Gaming Mouse', price: 60 },
{ name: 'UltraWide Monitor', price: 450 }
];
const priceTags = products.map(product => `$${product.price}.00`);
// priceTags is now ["$120.00", "$60.00", "$450.00"]
Clean, declarative, and it doesn't touch the original products array. I can't stress enough how important that "immutability" is when you start working with frameworks like React.
Sifting Through the Noise with Filter
While map changes the value of the elements, filter changes the number of elements. It runs a test (a predicate) on every item; if the function returns true, the item stays. If false, it's gone.
Imagine you only want to show the user the items that are actually affordable based on their budget:
const budget = 150;
const affordableProducts = products.filter(product => product.price <= budget);
// affordableProducts is now [{ name: 'Mechanical Keyboard', price: 120 }, { name: 'Gaming Mouse', price: 60 }]
The beauty here is that you can chain these. You can filter a list and then immediately map the results into a new format in one fluid motion.
The Swiss Army Knife: Aggregating with Reduce
reduce is the one that usually trips people up, mostly because the syntax is a bit weirder. But think of it this way: map and filter return arrays. reduce returns one single value. It "reduces" the entire array down to a total, an object, or even a different array.
It takes two arguments: a callback function and an initial value. That initial value is your "accumulator"βthe snowball that gathers data as it rolls through the array.
const cartTotal = products.reduce((accumulator, product) => {
return accumulator + product.price;
}, 0); // 0 is the initial value of the accumulator
console.log(cartTotal); // 630
If you forget that 0 at the end, JavaScript will use the first element of the array as the starting point, which is a recipe for disaster if your array contains objects instead of numbers. Always provide an initial value; it'll save you an hour of scratching your head in the debugger.
π Practical Task
Exercise: Processing User Activity Logs
You are building a monitoring dashboard. You have an array of log objects, and you need to extract a specific piece of intelligence from them. Your goal is to calculate the total number of characters across all "Error" messages, but only for logs that happened in the 'Production' environment.
The Data:
const logs = [
{ level: 'info', env: 'Production', message: 'Server started' },
{ level: 'error', env: 'Production', message: 'Database connection failed' },
{ level: 'error', env: 'Staging', message: 'API timeout' },
{ level: 'error', env: 'Production', message: 'Null pointer exception in User Controller' },
{ level: 'info', env: 'Staging', message: 'Cache cleared' },
];
Your Requirements:
- Use
filterto keep only the logs wherelevelis 'error' ANDenvis 'Production'. - Use
mapto transform those filtered logs into an array of just themessagestrings. - Use
reduceto sum up the total length (number of characters) of those messages. - Log the final total to the console.
There are no comments for now.