DEV Community

Discussion on: JavaScript’s Reduce Method Explained By Going On a Diet

Collapse
 
1hko profile image
1hko • Edited

The quoted result from the last reduce

/*total object is
{calories: 2100, carbs: 60, fat:65}
*/

is actually

// { name: 'steak', calories: 2100, carbs: 60, fat: 65 }

And the input foods is mutated too... :(

reduce enables functional style so we end up with really bad headaches if mix it with imperative-style thinking (+=). The same is true for map, filter, and the rest of the functional friends.

JavaScript is a very loose language though and so it allows us to do all sorts of reckless things. I will try my best to help you. Using pure functions will avoid setting up traps that might surprise us later.

Below total is a brand new value, foods is not mutated

const total =
  foods.reduce
    // pure function, operates only on its inputs, has no side-effects
    ( (sum, food) =>
        ({ calories: sum.calories + food.calories
         , carbs: sum.carbs + food.carbs
         , fat: sum.fat + food.fat
        })

    // don't forget about initial sum
    , { calories: 0 
      , carbs: 0
      , fat: 0
      }
    )

The arguments we're passing to reduce are useful on their own. Giving them a name communicates intent more clearly and promotes reuse in other areas of our program.

const emptyFood =
  { calories: 0
  , carbs: 0
  , fat: 0
  }

const addFood = (x, y) =>
  ({ calories: x.calories + y.calories
   , carbs: x.carbs + y.carbs
   , fat: x.fat + y.fat
  })


const sumFood = (foods = []) =>
  foods.reduce(addFood, emptyFood)


console.log(sumFood(foods))
// { calories: 2100, carbs: 60, fat: 65 }

Providing the initial sum makes sumFoods a pure function, one the functional programmer can rely upon

console.log(sumFoods([]))
// { calories: 0, carbs: 0, fat: 0 }

Without an initial sum, if you try to reduce an empty array, your program will throw an error, which is a side effect, which would make your function impure, and therefore unreliable – headaches!

Collapse
 
kbk0125 profile image
Kevin Kononenko

Hey 1hko, thanks for your thorough response! I learned quite a few things from it that I didn't know :)

I wrote this as the first resource that someone should read when they want to learn reduce, so it is always tough for me to figure out how much to specify in there vs. how much they will need to learn on their own.

I added a final code block with the initial value for the object and an explanation on why you need to create an initial value. I think you are right, the previous version would have led people into a trap potentially.

Collapse
 
1hko profile image
1hko

I agree it's very challenging to determine how much information to include. It's easy to overwhelm the learner!

I'm happy to have contributed to your post. Happy to discuss any time.