Level 4, Real Data & Architecture, Chapter 14 of 24
Arrays & Objects Deep Dive
Why this matters
Every real application is, underneath its buttons and colors, a pile of data that needs to be organized, filtered, and transformed. A shopping cart is an array of product objects. A social feed is an array of post objects, each containing an array of comment objects. Once you can confidently reshape these structures, you can build almost anything.
So far you've used arrays and objects mostly to hold values. Now it's time to treat them as the primary tool for solving problems. Instead of writing loops with manual counters and temporary variables, you'll learn the built-in array methods that let you describe what you want, not how to get it step by step. This shift in thinking is one of the biggest jumps you'll make as a developer.
The lesson
From loops to array methods
You already know how to write a for loop to walk through an array and do something with each item. That skill doesn't go away, but modern JavaScript gives you higher-level methods that express intent more clearly. array.map() transforms every item into something new and returns a new array of the same length. array.filter() keeps only the items that pass a test and returns a shorter (or equal) array. array.reduce() boils an entire array down into a single value, like a total, an average, or even a brand-new object. Together these three methods cover the vast majority of data-shaping tasks you'll encounter, from formatting prices to building summary statistics.
1const products = [2 { name: "Notebook", price: 4.5 },3 { name: "Headphones", price: 89 },4 { name: "Pen", price: 1.2 },5];67const affordable = products8 .filter((p) => p.price < 10)9 .map((p) => `${p.name}: $${p.price.toFixed(2)}`);1011console.log(affordable); // ["Notebook: $4.50", "Pen: $1.20"]reduce is the most flexible and, at first, the trickiest of the three. It takes a function that receives an accumulator (the value built up so far) and the current item, and it returns the updated accumulator. You also pass a starting value. Think of it like rolling a snowball down a hill: each item you pass gets folded into the growing result. reduce can compute a sum, group items by category, or even build a whole new object out of an array, which makes it worth practicing slowly and deliberately.
1const cart = [{ price: 12 }, { price: 8 }, { price: 25 }];23const total = cart.reduce((sum, item) => sum + item.price, 0);4console.log(total); // 45Nested objects and arrays
Real-world data is rarely flat. A single object often contains arrays of other objects, which themselves contain more objects. A blog post might have an author object, a tags array of strings, and a comments array where each comment has its own author object. To reach deeply nested values you chain dot notation and bracket notation together, and you use optional chaining (?.) to safely access properties that might not exist without crashing your program. Combined with array methods, you can now express things like 'get the names of everyone who commented on posts tagged javascript' in just a few readable lines.
array.map(fn)returns a new array with each item transformedarray.filter(fn)returns a new array keeping only items wherefnreturns truearray.reduce(fn, initial)folds the array down into one valuearray.find(fn)returns the first matching item, orundefinedobj?.propsafely reads a property that might be missing- Spread syntax (
...) copies arrays and objects instead of mutating them
A habit worth building now is avoiding direct mutation of arrays and objects whenever you can. Methods like push, splice, and directly assigning to a property change the original data in place, which can cause confusing bugs when other parts of your code still hold a reference to that same array or object. Instead, prefer creating new arrays and objects with spread syntax: const updated = [...items, newItem] or const updatedUser = { ...user, name: 'New Name' }. This pattern, called immutability, keeps your data predictable and is the foundation for how frameworks like React track changes.
1const user = { name: "Ana", age: 29 };2const olderUser = { ...user, age: user.age + 1 };34console.log(user); // { name: "Ana", age: 29 } unchanged5console.log(olderUser); // { name: "Ana", age: 30 }67const numbers = [1, 2, 3];8const withFour = [...numbers, 4];Sorting and grouping
array.sort() reorders an array in place, and by default it sorts based on string comparison, which produces surprising results for numbers (10 comes before 2). Always pass a comparator function when sorting numbers or objects: array.sort((a, b) => a.price - b.price) sorts ascending by price. Since sort mutates the original array, it's good practice to spread the array first if you need to keep the original order elsewhere: [...array].sort(...). Grouping, meanwhile, is usually done with reduce, building an object where each key is a category and each value is an array of matching items.
Try it yourself
Use map, filter, and reduce to transform the list of tasks below. Try filtering completed tasks, mapping titles to uppercase, and reducing to count total minutes.
Chapter boss project
Build a Data Transformer
You'll receive an array of order objects, each with a customer name, an array of items, and a status. Your job is to build a small dashboard that computes and displays several summaries: total revenue, orders grouped by status, and the top three customers by spend.
This project has no visual design requirements, it's about the data logic. Focus on chaining map, filter, and reduce cleanly rather than writing long manual loops, and avoid mutating the original orders array anywhere in your solution.
When you're done, your dashboard should update correctly if you add a new order object to the array and reload, without you changing any of your transformation logic.
- Start by writing one reduce call that computes total revenue across all orders and their items.
- Group orders by status by reducing into an object where each key is a status and the value is an array of orders.
- To find top customers, first reduce into a map of name to total spend, then convert that object into an array with Object.entries and sort it.
- Render results by mapping arrays of data into HTML strings and setting innerHTML once, rather than looping with document.createElement repeatedly.
Level-up checklist
Tick these off once each one is true for you.
