ECMAScript 5 introduced many in 2009, the majority of them being array methods like , , , , , . But let’s talk about my favorite one: . awesome features isArray forEach map filter every some reduce The method reduce The method executes a callback function (provided by the user) on each element of the array, resulting in a single output value. reduce reducer reducer The function takes four arguments: reducer Accumulator (acc) Current value (cur) Current index (idx) Source array (src) Your function’s return value is assigned to the accumulator, whose value is remembered across each iteration throughout the array and ultimately becomes the final, single resulting value. reducer Important: On each iteration, you must return the accumulator value for the next iteration (which will eventually be the final return value), or else the accumulator’s next (and ultimately final) value will be . undefined initialValue The method takes a second optional argument: . If not provided, the initial value of the accumulator will be the first element of the array, and the first iteration will point to the second element. If is provided, it will be the initial value of the accumulator, and the first iteration will point to the first element of the array. reduce initialValue initialValue Examples Summing numbers with/without an initial value numbers = [ , , ]; sum = numbers.reduce( accumulator + currentValue ); .log(sum); initialValue = ; sumWithInitialValue = numbers.reduce( accumulator + currentValue , initialValue); .log(sumWithInitialValue); const 1 2 3 // Without initialValue const ( ) => accumulator, currentValue // Prints 6 console // With initialValue const 3 const ( ) => accumulator, currentValue // Prints 9 console Without the initial value, the first iteration will have pointing to the first element of the array (1), and pointing to the second element of the array (2). accumulator currentValue Given the initial value, the first iteration will have an with the value of the given initial value (3), and will point to the first element of the array (1). accumulator currentValue Counting the number of occurrences in an array Let’s count the number of occurrences of words in the following and store the results in a map: How much wood would a woodchuck chuck If a woodchuck could chuck wood? He would chuck, he would, as much as he could, And chuck as much as a woodchuck would If a woodchuck could chuck wood. sentence = + + + + ; words = sentence.split( ); occurencesMap = words.reduce( { numOfOccurences = (occurences.get(word) || ) + ; occurences.set(word, numOfOccurences); occurences; } , ()); numOfWoodchucks = occurencesMap.get( ); .log(numOfWoodchucks); const "how much wood would a woodchuck chuck" "if a woodchuck could chuck wood " "he would chuck he would as much as he could " "and chuck as much as a woodchuck would " "if a woodchuck could chuck wood" const " " const ( ) => occurences, word const 0 1 return new Map const "woodchuck" // 4 console We initialize an empty map and use it as the initial value of the accumulator, initializing or updating the number of occurrences of each word as we iterate over the words in the sentence. These are only two examples, but by now you must have realized how awesome is, right? reduce It allows you to take an array and reduce its values to basically anything that can be derived from the data it holds. It also allows you to return any type of data, regardless of the type of the elements of the array. One Method to Rule Them All? Revisiting other ES5 array methods, we can see that each method uses the given callback function on the array and returns some kind of result. For example: transforms each element of the array, returning a new array. map checks if the given condition applies to every element in the array, returning the corresponding Boolean value. every Looks familiar, right? Using what we already know, let’s try to use to implement other ES5 array methods. reduce Note: we’ll add the new methods to ’s prototype in each example, where will point to the array on which we’re operating. Array this map The method creates a new array where each original element is transformed by the given callback. map() transformer Usage array = [ , , ]; doubled = array.map( num * ); .log(doubled); const 1 2 3 const => num 2 // Prints [2, 4, 6] console Using a transformer callback that doubles every number in the array, we get a new array where every element is twice its original value. With reduce operates on an array and returns a new array, so the accumulator has to be an array. map .prototype.mapWithReduce = { .reduce( { newElement = transformer(currentElement); newArray.push(newElement); newArray; }, []); } array = [ , , ]; doubled = array.mapWithReduce( num * ); .log(doubled); Array ( ) function transformer return this ( ) => newArray, currentElement const return const 1 2 3 const => num 2 // Prints [2, 4, 6] console Using , we start with an empty array accumulator and iterate over the array. We then apply the transformer callback on each element and push it to the accumulating array. reduce filter The method creates a new array with all elements that pass the test implemented by the provided function. filter() Usage array = [ , , , , , , , , , ]; evenOnly = array.filter( num % === ); .log(evenOnly); const 1 2 3 4 5 6 7 8 9 10 const => num 2 0 // Prints [2, 4, 6, 8, 10] console Using a test callback that filters out all odd numbers, we get a new array with all the even elements of the original array. With reduce Just like the previous example, filter also operates on an array and returns a new array, so the accumulator has to be an array. .prototype.filterWithReduce = { .reduce( { (tester(currentElement)) { newArray.push(currentElement); }; newArray; }, []); } array = [ , , , , , , , , , ]; evenOnly = array.filterWithReduce( num % === ); .log(evenOnly); Array ( ) function tester return this ( ) => newArray, currentElement if return const 1 2 3 4 5 6 7 8 9 10 const => num 2 0 // Prints [2, 4, 6, 8, 10] console Using , we start with an empty array accumulator and iterate over the array. We then use the tester callback to check if each element should be pushed to the accumulating array. reduce every The method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value. every() Usage array = [ , , , , ]; result = array.every( num < ); .log(result); const 1 2 3 4 5 const => num 10 // Prints true console Using a callback function that tests every element in the array, we get a boolean that indicates whether all elements pass the test. In this case, all elements are smaller than 10, and thus returns . every true With reduce operates on an array and returns a Boolean value, so the accumulator has to be a boolean. every .prototype.everyWithReduce = { .reduce( acc && tester(currentElement) , ); } array = [ , , , , ]; result = array.everyWithReduce( num < ); .log(result); Array ( ) function tester return this ( ) => acc, currentElement true const 1 2 3 4 5 const => num 10 // Prints true console Using , we start with a boolean accumulator value of (we’ll discuss the reason later on) and iterate over the array. We then chain the result of the tester callback to the accumulator using the logical AND ( ), to eventually return if all elements pass the test, and false . reduce true && true otherwise Why start with ? true If the array is empty, returns regardless of the test callback (even if the callback returns ). Else, if all elements fulfill the condition, the chaining of the initial value using the logical AND will eventually resolve to . If not, the chaining will eventually resolve to . every true false true true false some The method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value. some() Usage array = [ , , , , ]; result = array.some( num > ); .log(result); const 1 2 3 4 5 const => num 3 // Prints true console Using a callback function that tests every element in the array, we get a boolean that indicates whether any element passes the test. In this case, the fourth element is larger than 3, and thus returns . some true With reduce operates on an array and returns a boolean value, so the accumulator has to be a boolean. some .prototype.someWithReduce = { .reduce( acc || tester(currentElement) , ); } array = [ , , , , ]; result = array.someWithReduce( num > ); .log(result); Array ( ) function tester return this ( ) => acc, currentElement false const 1 2 3 4 5 const => num 3 // Prints true console Using , we start with a boolean accumulator value of (we’ll discuss the reason later on) and iterate over the array. We then chain the result of the tester callback to the accumulator using the logical OR ( ), to eventually return if any element passes the test, and otherwise. reduce false || true false Why start with ? false If the array is empty, returns regardless of the test callback (even if the callback returns ). some false true Else, if any element fulfills the condition, the chaining of the initial value using the logical OR will eventually resolve to . If not, the chaining will eventually resolve to . false true false Disclaimer (every and some) The method executes the provided callback function once for each element present in the array until it finds the one where callback returns a falsy value (a value that becomes when converted to a boolean). If such an element is found, immediately returns . every false every false Similarly, the method executes the callback function once for each element present in the array until it finds the one where callback returns a value (a value that becomes when converted to a boolean). If such an element is found, immediately returns . some truthy true some true However, there’s no pretty way to . This means that while both implementations (both the original method and the corresponding implementations using ) have a runtime of , the original implementations are likely to terminate without having to iterate over the entire array, making them more efficient. terminate reduce mid-loop every/some reduce O(n) filter + map Given an array of numbers, what is the most efficient way to filter out all even elements and square the remaining ones (using ES5 methods)? Let’s try followed by : filter map array = [ , , , , , , , , , ]; tester = num % === ; transformer = num * num; result = array.filter(tester).map(transformer); .log(result); const 1 2 3 4 5 6 7 8 9 10 const => num 2 1 const => num const // Prints [1, 9, 25, 49, 81] console We create a tester function that keeps only odd elements and a transformer function that squares the given elements. We then use these two callback functions when chaining the and methods, and return the desired array. filter map Let’s use what we know about implementing and with , only this time let’s combine them in one go. filter map reduce array = [ , , , , , , , , , ]; tester = num % === ; transformer = num * num; result = array.reduce( { (tester(currentElement)) { newElement = transformer(currentElement); newArray.push(newElement); } newArray; }, []); .log(result); const 1 2 3 4 5 6 7 8 9 10 const => num 2 1 const => num const ( ) => newArray, currentElement if const return // Prints [1, 9, 25, 49, 81] console We use the same tester and transformer functions to test if each element should be kept in the array and transform it if it should. This approach saves us the need to create an intermediate array of filtered values, and we get a slightly more efficient algorithm as we don’t have to iterate over two different arrays (the original and the intermediate). Conclusion These were a few examples of how to use the powerful method to implement other ES5 methods. reduce How do you use it in your day-to-day coding? Share in the comments! Sources by w3schools ES5 features by MDN web docs. Every method documentation in this article is taken from here. Javascript array methods