This is my third article on getting Started

One, foreword

Reduce is one of my favorite higher-order functions in JavaScript array objects. Reduce is very powerful. Almost all high order functions can be implemented by Reduce and it allows us to write JavaScript gracefully

But Reduce is also a “hard to understand” method, now let’s understand reduce step by step.

2. Reduce – syntax

Let’s see how MDN describes Reduce.

Array. Reduce: Array. Reduce: Array. Reduce: Array. Reduce: Array

// The simplest reduce example is array summation
const array = [1.2.3.4];
const sum = array.reduce((accumulator, currentValue) = > {
    return accumulator + currentValue
})
console.log(sum) // The sum of the array is 10
Copy the code

Before we can learn an API, we need its functions and functions. What is it to do namely, what effect can he bring, just so called know oneself know the enemy hundred victories ~

Learning an unfamiliar API basically follows these steps:

  1. Find the documentation and read the introduction to the API
  2. API syntax: parameter definition, return value, API structure.
  3. Write code tests and experiences based on examples

Array.reduce

Array.reduce() accepts a function as an accumulator Array, starting with each value (from left to right), and finally returns the function,

Grammar:

array.reduce(function callback(accumulator, currentValue, index, array) {
  // Return the result of executing some logic as the value of the next accumulator
  // The return value can be: object, array, string, number, etc.. Reduce flexible fundamental!!
}, [initialValue])
Copy the code

This method takes two parameters:

  • callback(…) (Must)(accept 4 arguments)
    • Accumulator (the initial value, or the value returned by the end of the calculation)
    • CurrentValue (current element value)
    • CurrentIndex (current element index)
    • SourceArray.
  • InitialValue (Optional).
    • If no default value is passed, the callback function is executed for the first time starting at index 1. The accumulator value is the first value in the array
    • If passed, it starts at array index 0 and accumulato is the default value
    • If there is no default value and the array is empty, an error is reported!!
    • Initialized values are also the basis for flexible changes to be passed and reduced

Note:

  • Reduce () does not execute the callback function for an empty array
  • Reduce () will report an error if executed on an empty array with no initial value!!
  • Reduce () does not change the array

Simple animation to understand Reduce

  1. Reduce executes the function we wrote for each element of the array
  2. The value of function return is the value of the next function accumulator, which is the input value.
  3. The execution sequence is ascending, from left to right

See the power of Reduce

Let’s see the power of Reduce through a simple case!!

Title: Array object: remove id, remove empty comments, and return an array of data user ids

let user = [
  {id: 1.content: 'Hahaha'},
  {id: 2.content: ' '},
  {id: 2.content: ' '},
  {id: 3.content: 'Hey hey hey'},
  {id: 3.content: 'Hey hey hey'},
  {id: 3.content: 'Hey hey hey'},
  {id: 4.content: 'Drip drip'},
  {id: 5.content: 'Uh uh uh'},
  {id: 6.content: 'Dah dah dah'},
  {id: 7.content: 'Dong Dong dong'},]Copy the code

Common practices:

// Simple ~ doesn't it smell good? (ps: Just an example, there are many other ways ~)
Array.from(new Set(user.filter(e= > e.content).map(e= > e.id)))
// [1, 3, 4, 5, 6, 7]
Copy the code

But!! Have you ever wondered if these syntactic candies are concise enough, but how many times are they traversed, and whether the semantics are obvious enough? There’s another way we can do this once and for all

Use the reduce

user.reduce((accumulator, value) = > {
    const id = value.id 
    returnid && ! accumulator.includes(id) ? [...accumulator, value.id] : accumulator }, [])// [1, 3, 4, 5, 6, 7]
// Map filter from Set... What about these operations?
Copy the code

Expand your knowledge: What? With the… Extended operator too much, too much remainder?

Use the comma operator

  • The comma operator is a binary operator that executes the operand to the left of the operator, then the operand to the right, and returns the value of the right-hand operand.
user.reduce((accumulator, value) = > {
  const id = value.id 
  returnid && ! accumulator.includes(id) ? (accumulator.push(value.id), accumulator) : accumulator }, [])Copy the code

4. Everything can be reduced

1. Reduce implements the map method

First, let’s see what the map method does: the map() method returns a new array whose elements are the processed values of the original array elements.

const arr = [{name:'Amy'.age: 10}, {name:'Bob'.age: 20}]

The usage / / map
arr.map(itme= > itme.name) // ["Amy", "Bob"]

// Use extended operators and default parameters
arr.reduce((total, value) = > [...total, value.name], [])
// ["Amy", "Bob"] 
Copy the code

Now, how do we do that

  1. We first give the default an empty array because the map method returns an array.
  2. […total, value.name] We take the name out and put it in the array, and the value of return is passed to the next function’s total, which is: [‘Amy’].
  3. The function continues… Finally, return the accumulated array [“Amy”, “Bob”]
  4. Ps: Total is actually the accumulator above. If this is not familiar advice, I will look back at the syntax and write code according to the case to deepen my understanding.
  5. The above method uses ES6’s arrow function and expansion operator for shorthand operations

2. Reduce implements the filter method

The filter() method creates a new array by examining all the elements in the specified array that meet the criteria

const arr = [{name:'Amy'}, {name:'Bob'}]

/ / filter usage
arr.filter(itme= > itme.name === 'Amy')
// [{name: "Amy"}]

// Use a ternary expression, return it in an extended way if it is true, and return the original value if it is false
arr.reduce((total, value) = > value.name === 'Amy' ? [...total, value] : total, [])
// [{name: "Amy"}]
Copy the code

Let’s see how:

  1. We first give the default an empty array because the filter method returns an array.
  2. We take advantage of the fact that the reduce return value is the total value of the next function. We use a ternary expression, and if the expression is true, we pass it through the array. If false returns a change to the total array.
  3. Clever use of callback functions and return values is the power of Reduce.

3. Reduce replaces Map + filter

const arr = [{name:'Amy'.age: '18'}, {name:'LaLa'.age: '18'}, {name:'Bob'.age: '22'}]

// Filter + map
arr.filter(item= > item.age === '18').map(item= > item.name)

// Use extended operators and default parameters
arr.reduce((total, value) = > value.age === '18' ? [...total, value.name] : total, [])
Copy the code

Let’s see how it works:

  1. The default value is defined as above, and the data is processed by the return value.
  2. Over time you’ll realize that the pattern is the same. First you need to know what you need (return value, initial value, what you want to pass to the next function).

4. Reduce implements some methods

First, we need to know the purpose of the method before we can use our method to rewrite.

The some() method returns true if one of the conditions is met

const arr = [{name:'Amy'.age:18}, {name:'Bob'.age:20}]

// some is true when one of the conditions is true
arr.reduce((total, value) = > total || value.age > 18.false)
Copy the code

Let’s see how it works:

  1. We want to ask: “Return true if one condition is met.”
  2. When we return the use of “| |” short-circuit characteristics of the operator
  3. The default value is false. Total returns true if a condition is met. The short circuit operator will always return true.

5. Reduce implements every

Every () returns true if all conditions are met

const arr = [{name:'Amy'.age:18}, {name:'Bob'.age:20}]

Return true if all conditions are met
arr.reduce((total, value) = > total && value.age > 18.true)
Copy the code

Let’s see how it works:

  1. The logic here is the same as the logic in some. We use the properties of every method to add “&&” and logic symbols. Make every element to be judged, and total becomes false if one condition is not met. In && it is always false

6. Reduce to implement flat method

The flat() method recurses through the array at a specified depth and returns a new array combining all the elements with the elements in the subarray it traverses.

// Simplified version:
var arr = [1.2.3.4[1.2.3.4.5[2.3.4]]]

function arrFlat(data) {
  return data.reduce((total, value) = > {
    return Array.isArray(value) ? [...total, ...arrFlat(value)] : [...total, value]
  }, [])
}
arrFlat(arr)
// (12) [1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4]
Copy the code
/ / the full version
var arr = [1.2.3.4[1.2.3.4.5[2.3.4]]]

function arrFlat(arr, depth = 1) {
  return depth 
    ? arr.reduce((total, currentValue) = > {
      return Array.isArray(currentValue) ? [...total, ...arrFlat(currentValue, depth - 1)] : [...total, currentValue]
    }, []) 
    : arr
}

arrFlat(arr, 2)
// (12) [1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4]
Copy the code

Let’s see how it works:

  1. Here we use the recursive arrFlat function
  2. The default value is 1. If depth is 0, the element is returned. If depth is not 0, there is a deeper level. Depth is important to control the level of reduce traversal
  3. Deconstruction is also important

7. Reduce implements the de-duplication of arrays

const arr = ['a'.'a'.'b'.'b'.'c'.'c'.'d']

arr.reduce((total, value) = >  total.includes(value) ? total : [...total, value], [])
// (4) ["a", "b", "c", "d"]
Copy the code

Let’s see how it works:

  1. We use includes to determine if there is an array in the total group. If there is, we return the array. If not, we add an array.

Five, the summary

There are so many ways to reduce that it is hard to complete all of them, but I believe you have understood the power of Reduce through these classic cases.

Everything can be reduced, you can do that but you don’t have to.

This article just wants to show you how powerful Reduce is. Should you use Reduce in every case? There is no best way, only the best way for you.

While it may seem mind-boggling and “incomprehensible,” learning it can only be to your advantage. What makes the reduce() method powerful is the ability to write different methods in the Callbakc callback and provide space for each element of the array.