Need help understanding reduce

Tell us what’s happening:

I believe the best way to learn something is to try to explain it, but I live alone with nobody to talk to, so whenever I feel like I don’t quite understand something, I somewhere to post my thoughts. I’d like to try here and see if my understanding of the problem is correct. The curriculum doesn’t really do a good job of introducing how reduce works, so I will stumble through my understanding of it after watching a couple of videos on the topic.

The first line:

return s.split(' ')

This splits the string into an array of words. I don’t think the order is maintained here, but it’s not important to the task at hand.

the second line:

.reduce (function (x, y) {

I don’t really like that whoever wrote this line used “x” and “y”, but I think x is supposed to refer to the current largest word and y refers to the next word in sequence that’s being examined. In the videos, “x” is the accumulator and I understand that this value is supposed to persist throughout the function while “y”, the current value is cycled and compared to “x” in some fashion, whether it’s added, subtracted, replaced or etc. This line, by itself, does not yet seem to instruct the function what to do between x and y. That part I think comes after.

return Math.max(x, y.length)

This line tells the function to compare between “x” and the length of “y” and choose the larger of the two elements. The code explanation tells me that the “0” at the very end of this code instructs the function where to start “x”. If the 0 isn’t there, I assume I’ll get an error because with no value to compare with “y”, Math.max has nothing to work with?

Finally, what kinds of problems will the reduce function work best with? For loops?

Your code so far


function findLongestWordLength(s) {
return s.split(' ')
  .reduce(function(x, y) {
    return Math.max(x, y.length)
  }, 0);
}


findLongestWordLength("The quick brown fox jumped over the lazy dog");

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36.

Challenge: Find the Longest Word in a String

Link to the challenge:
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/find-the-longest-word-in-a-string

2 Likes

I think you got the gist of it. If you haven’t already, check out the documentation for reduce on MDN:

It can be very confusing to read documentation like this as a beginner, but it’s a very important skill to develop since there will always be things to learn or review. Videos are not always the best way to do this.

In the Example section of the page there are many examples of problems that can be solved with reduce.

The order is maintained.

From the documentation I linked above, that zero is the initial value for x in the callback function. If you leave it out then the first time the callback function is executed, x will equal the first value in the array and y will also be first value in the array. Then the callback function would execute, returning a new accumulator (x) for the second time. But since you need the accumulator to track a number instead of a string (the type of data in the array), this wouldn’t work. So you make the initial x a number (0) instead.

…Sorry a bit complicated to explain! But anyways the main point is that the zero would not be needed for every application of reduce. For example: if you were just comparing the strings in the array and not returning their length.

2 Likes

I think this is an A+ quality question!

2 Likes

This was a really well written question. You worked through the logic well. In answer to your final question, reduce is used when you want to turn an array into a single value. Obvious uses for this are mathematical (such as finding the sum of all numbers in an array), but you can do some pretty powerful things with it.

2 Likes

I like using reduce to convert an array of object property values to create an HTML string to be used to add to the DOM.

Example:

const moviesObj = [
   {
    title: 'Star Wars',
    director: 'George Lucas',
    genre: 'Science Fiction'
  },
   {
    title: 'Jaws',
    director: 'Stephen Spielberg',
    genre: 'Thriller'
  },
   {
    title: 'Dumb and Dumber',
    director: 'Peter Farrelly',
    genre: 'Comedy'
  },
];

const moviesHTML = moviesObj.reduce((html, { title, director, genre }) => html += `
  <div class="movie">
    <div class="title"><strong>Title:</strong> ${title}</div>
    <div class="director"><strong>Director:</strong> ${director}</div>
    <div class="genre"><strong>Genre:</strong> ${genre}</div>
  </div>
`, '');
document.getElementById('moviesDiv').innerHTML = moviesHTML;

as @ArielLeslie said:

reduce is used when you want to turn an array into a single value.

and that value can be anything.

I use reduce for any kind of data manipulation:

  • merging and modifying objects leveraging ES6 methods on Objects
  • complex “comparison” that requires multiple chaining filters can usually be achieved with a single reduce
  • piping functions

among the other mentioned before i personally think it’s a great tool to have under your belt :+1:

1 Like

I have trouble following this code or what exactly it means to create an HTML string to add to a DOM. In this example, are you taking the properties of the movie and adding it to the HTML string? How does the function determine which property to go with? Given what reduce does, I assume only one of these properties will be tied to the HTML? If I even understood that right.

So far, all of the applications of reduce I’ve seen have been numerical in nature, which makes comparisons easier to understand since you can easily determine one value to be greater than, less than, or equal to another value to be compared. But strings have no such inherent quality, so when I see a problem that does not rely on any inherent numerical quality, it’s not very natural for me to think, “this is something that reduce could effectively handle”.

let’s start saying that you can implement (almost) any other method with reduce

in the above example, the second argument of the reduce callback is { title, director, genre }, this is in place destructuring, and will make the value of the three properties referenced with a single variable instead of dot/bracket notation

the other thing with which you may not be familiar with is temperate literals
if you use backticks to surround a string, you can reference variables inside the string with ${variable} and the variable will be added there

the accumulator starts with an empty string, and at each iteration a string is appended to the accumulator html += ...

for the DOM, that stands for Document Object Model.
you can change the html of the page with javascript directly with dom methods, those could be something you can research. (last line of code is what does that, if you create an element on codepen with moviesDiv id you can paste that code in the JS box and see it working)

@Jengas2015 Let me rewrite my assignment to moviesHTML in the hopes that it makes more sense. I was using a template literal as well as function parameter destructuring as well as arrow function syntax…

const moviesHTML = moviesObj.reduce(function(html, movie) {
  html += '<div class="movie">';
  html += '  <div class="title"><strong>Title:</strong> ' + movie.title + '</div>';
  html += '  <div class="director"><strong>Director:</strong> ' + movie.director + '</div>';
  html += '  <div class="genre"><strong>Genre:</strong> ' + movie.genre + '</div>';
  html += '</div>';
  return html;
}, '');