Here's where it all comes together. Since map and filter both return arrays, you can chain them: call another method directly on the result. Each method is a station on the assembly line:
const products = [
{ name: "Laptop", price: 4500, inStock: true },
{ name: "Phone", price: 2200, inStock: false },
{ name: "Headphones", price: 350, inStock: true },
{ name: "Charger", price: 80, inStock: true },
{ name: "Tablet", price: 3100, inStock: true },
];
const affordable = products
.filter((p) => p.inStock)
.filter((p) => p.price < 4000)
.sort((a, b) => a.price - b.price)
.map((p) => `${p.name}: $${p.price}`);
console.log(affordable);
It prints
[ 'Charger: $80', 'Headphones: $350', 'Tablet: $3100' ]
Read it from top to bottom like a recipe:
- Start with all the products.
- Keep only the ones in stock.
- Keep only the ones under $4,000.
- Sort them from cheapest to most expensive.
- Turn each one into a nice label.
Putting each method on its own line, starting with a dot, makes long chains much easier to read. This style of code, where you describe what you want instead of writing out every step of how to loop, is called declarative programming, and it's one of the things that makes modern JavaScript so pleasant to write.
(Sorting after filtering is safe here, by the way: filter already returned a brand-new array, so sort is rearranging that copy, not the original products.)