Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Array Iteration Methods Combining Array Methods Combining filter() and reduce()

Samuel Kleos
seal-mask
.a{fill-rule:evenodd;}techdegree
Samuel Kleos
Front End Web Development Techdegree Student 12,719 Points

What if.. 🤔 We reordered the array.

I have not progressed past this because this has got me (perhaps unnecessarily) flustered.

I don't give up. I just go through all 7 stages of grief repeatedly until I'm done.

My understanding of the callback passed into the reduce() method is as such:

  • "The returned value is passed to the next iteration of the callback function." I learned this myself (the docs I think)
  • A return will escape a loop.

For the life of me I could not work out how to traverse the array twice to compare the value of the accumulator against every single value without creating some infinite chain of if statements.

Turns out the problem is the problem.

If you take a look at this: I simply reordered the array, What I really need clarity on is why 'ballpoint pens' isn't returned, given the previous iterations' price is higher. I feel like I have missed a fact.

const products = [
  { name: 'hard drive', price: 59.99 },
  { name: 'ballpoint pens', price: 4.49 },
  { name: 'lighbulbs', price: 2.59 }, // higher > current -> return higher and end loop
  { name: 'paper towels', price: 6.99 },
  { name: 'flatscreen monitor', price: 159.99 },
  { name: 'cable ties', price: 19.99 },
];

    // Result: { name: 'paper towels', price: 6.99 }
highestU10 = products
    .filter(product => product.price < 10)
    .reduce((higher, current) => {
        if (higher.price > current.price) {
            return higher;
        }
        return current;
}, {})

console.log(highestU10);

Edit: I suspect this is how it works – the return value is returned every iteration of the callback, so every time it discovers something bigger than before, the bigger value is returned as the accumulator.

Here's a better way to put it:

highestU10 = products
    .filter(product => product.price < 10)
    .reduce((higher, current) => higher.price > lower.price? : higher : lower, {})

1 Answer

Steven Parker
Steven Parker
229,921 Points

While a reduce does perform iteration internally, it's not a loop from the perspective of the JavaScript engine. So a "return" does not cause an early end to the iteration. The "return" here merely ends the function that is being called for each iteration and passes back a value. Since the iteration will always include every element, the order of items in the array is not important.

Also, your optimization using a ternary is a good idea, but you have some syntax issues. Here's a corrected version:

    .reduce((higher, current) => higher.price > current.price ? higher : current);

Note that it's also not necessary to assign an empty object as an initial value.