DEV Community

Discussion on: .map(), .filter(), and .reduce()

Collapse
 
therealkevinard profile image
Kevin Ard

I was on mobile last night and I've been busy today, so I honestly didn't expect to have a reply. ...but whaddaya know, I JUST NOW used a reduce lol.

The init value - technically - protects you from a TypeError if you encounter an empty array. init, if not provided, is implicitly taken from arr[0]. If !arr[0]... Muerte.

Here, I'm writing a cypress e2e test that finds all the card rows in the page and guarantees the contained cards are the same height. To do so, I sum the heights of all the cards, divide that by cards.length, and compare the final avg to cards[0]. (a variance inside will break the cards[0]===avg, I hope :D)

Not such a problem with Cypress, but it could be possible that there are no cards in the row.

Most uses of reduce aren't for summing, though. Its return - more often than not - is a complex object, rather than a simple value. In these cases:

  1. arr[0] can't properly init the product, because product and items have very different structures.
  2. providing an init that models the outcome helps self-document the code (other devs see in the call an idea of what to expect), and it save you a ton of checks internally.
it.only('cards within a row are equal-height', () => {
    cy.get('[data-t="card-row"]')
        .each(row => {
            let heights = []
            cy.wrap(row)
                .find('div.card')
                .each(card => heights.push(Math.floor(card.innerHeight())))
                .then(() => {
                    let avgHeight = heights.reduce((prev, curr) => prev + curr, 0) / heights.length
                    expect(heights[0]).to.eq(avgHeight)
                })
        })
})
Thread Thread
 
pickleat profile image
Andy Pickle

Very cool! Thanks for sharing this example.