Good Vs. Evil - Battle For Middle Earth - CodeWars This is the code that I'm submitting for the "Good vs Evil" Kata on CodeWars:

https://www.codewars.com/kata/good-vs-evil/train/javascript

function goodVsEvil(good, evil) {
  good = good.split(' ');
  evil = evil.split(' ');

  //hobbits, men, elves, etc
  let goodWorth = [1, 2, 3, 3, 4, 10];
  //orcs, men, wargs, etc  
  let evilWorth = [1, 2, 2, 2, 3, 5, 10];

  let goodArmyPoints = [];
  //multiply goodWorth by type:
  for (let i = 0; i &lt; goodWorth.length; i++) {
    goodArmyPoints.push(good[i] * goodWorth[i]);
  }

  goodArmyPoints = goodArmyPoints.reduce(function (sum, value) {
    return sum + value;
  });

  let evilArmyPoints = [];
  for (let j = 0; j &lt; evilWorth.length; j++) {
    evilArmyPoints.push(evil[j] * evilWorth[j]);
  }

  evilArmyPoints = evilArmyPoints.reduce(function (sum, value) {
    return sum + value;
  });

  if (evilArmyPoints &lt; goodArmyPoints) {
    return "Battle Result: Good triumphs over Evil";
  } else if (evilArmyPoints &gt; goodArmyPoints) {
    return "Battle Result: Evil eradicates all trace of Good";
  } else {
    return "Battle Result: No victor on this battle field";
  }

}


But I'm not sure what:

goodArmyPoints = goodArmyPoints.reduce(function (sum, value) {
    return sum + value;
  });


is doing exactly. 

I see that reduce "executes a reducer function (which I've provided?) on each member of the array, resulting in a single output value".

But can someone please walk me through what .reduce(function (sum, value) is doing, exactly? Where is this function coming from? What are sum and value? 

I'm still learning JavaScript and this is new to me. Thanks.
I see at least two things about your code that could be improved.

  let goodArmyPoints = [];
  //multiply goodWorth by type:
  for (let i = 0; i &lt; goodWorth.length; i++) {
    goodArmyPoints.push(good[i] * goodWorth[i]);
  }

  goodArmyPoints = goodArmyPoints.reduce(function (sum, value) {
    return sum + value;
  });


Here you allocate a whole array to store the results of multiplications, and then reduce over it. This extra array is wasteful. It would be much clearer and cleaner (and faster) to write simply

  let goodArmyPoints = 0;
  for (let i = 0; i &lt; goodWorth.length; ++i) {
    goodArmyPoints += good[i] * goodWorth[i];
  }




Another confusing thing about your original code is that in the line

  goodArmyPoints = goodArmyPoints.reduce(...);


you are assigning over goodArmyPoints. And not just assigning over its value, but actually changing its type — from "array of numbers" to "just a single number."

Since a variable's name usually reflects what's stored in it, and what's stored in it is usually a function of its type, it follows that variables of different types rarely end up with the same name. For example, if I had two variables, one that stored an array of point-values and one that stored a single point-value, I would probably name them goodScores and goodScore, or goodPartialScores and goodTotal, or something like that. But I definitely would not give them the same exact name!

By giving each variable a unique name, and never changing the type of an existing variable, we increase the understandability of the code. Because now, when the reader asks, "What is the type of variable goodArmyPoints?", we can actually give an answer! In your original code, if the reader asks "What is the type of variable goodArmyPoints?", all we can do is hedge: "Well, at this point in the code it's an array, but when we use it two lines later, it's a number..." That's a more complicated and confusing answer, which is just another way of saying that your original code is more complicated and confusing than the simplified code above.