Remember the clever reduce method in Array

Reduce, a seemingly ordinary thing, is actually a very useful method. Many people use it more as a summation tool, but in fact it has more uses. It depends on how we use it. Discover its usage and talk about it slowly next.

reduce() is the merging method of JavaScript Array array. Like forEach, map, some, every and other iteration methods, each item of the array will be traversed, but reduce can simultaneously operate on the results generated by traversing the previous array items and the current element. This is something that other iterative methods cannot do, which gives it different capabilities.

1. reduce syntax

arr.reduce(function(prev, cur, index, arr) {
  ......
}, init)
  • arr represents the original array;

  • prev represents the value returned when the callback was last called, or the initial value init. When the initial value is not specified, the value is the first element of the array, and cur is the second element of the array at this time;

  • cur represents the array element currently being processed;

  • index represents the index of the element currently being processed. If init is specified, the index is 0. If init is not specified, the index is 1;

  • init represents the initial value and has no requirements on the type.

It seems that several variables are quite troublesome, but in fact there are two main ones to remember: prev and cur, and there is also an initial value init to pay attention to.

2. reduce use cases

Next, let’s talk about the use cases of reduce. Of course, there are not only the following usage methods, but the following are more commonly used. Specific and higher-level ones can be expanded and implemented when needed.

1. Sum

The first is of course the summation that we are all familiar with. This is relatively simple.

var arr = [12, 42, 12, 61, 73, 19]
var sum = arr.reduce(function(prev, cur){
  return prev + cur
}, 0)
console.log(sum) // 219

Because the initial value 0 is passed in, prev is 0 at the beginning, and cur is the first item 12 of the array. After the addition, the value is 12 and the value is returned as the prev of the second addition, and then combined with the second item of the array. The terms are added, then returned, and then continued in sequence, finally obtaining the result 219.

This is a small thing. Let’s increase the difficulty. We require the sum of a certain attribute in the object array.

var goods = [
  {type: 'slipper', price: 24}, 
  {type: 'bowl', price: 11},
  {type: 'chopsticks', price: 5},
  {type: 'plate', price: 9}
]

var sum = goods.reduce(function(prev, cur) {
  return prev + cur.price
}, 0)

console.log(sum) // 49

The principle is still the same, but don't forget to give an initial value of 0, otherwise the result will be [object Object] 1159, because prev is the first item at this time, which is an object. After type conversion, valueOf is called at this time, and the returned object itself It is not an operable value. Calling toString again returns the object string [object Object], and the rest becomes string concatenation.

 

The initial value can also be an object

var sum = goods.reduce(function(prev, cur) {
  prev.sum = prev.sum + cur.price
  return prev
}, { sum: 0})

console.log(sum) // { sum: 49 }

It can be seen that there is no requirement for the type of the initial value, as long as the operation in the function is correct and the prev after the operation is returned.

 

The above summations are all superpositions of a single dimension. Now let's look at the superposition of multiple dimensions, which means that it involves the summation of multiple attributes rather than simply the sum of one attribute. Now let's change the above use case requirements. If there is a product discount table for various events, now we need to calculate the total price of the products under each discount.

var goods = [
  {type: 'slipper', price: 24},
  {type: 'bowl', price: 11},
  {type: 'chopsticks', price: 5},
  {type: 'plate', price: 9}
]

var discount = {
  dis1: 0.6,
  dis2: 0.7,
  dis3: 0.8
}

var initialState = {
  dis1Total: 0,
  dis2Total: 0,
  dis3Total: 0
}

var sum = goods.reduce(function(outerPrev, outerCur) {
  return Object.keys(discount).reduce(function(innerPrev, innerCur) {
    outerPrev[`${innerCur}Total`] += outerCur.price*discount[innerCur]
    return outerPrev
  }, {})
}, initialState )

console.log(sum) // {dis1Total: 29.4, dis2Total: 34.3, dis3Total: 39.2}

In fact, it feels a bit like adding a loop within the loop body, which is quite easy to understand once you understand it.

2. Find the best value

Reduce can also be used to find the maximum or minimum value of a numeric array. The following uses the maximum value as an example.

var arr = [12, 42, 12, 61, 73, 19]
var max = arr.reduce((prev, cur) => {
  return prev > cur ? prev : cur
})
console.log(max) // 73

Since no initial value is provided, prev is the first element 12. In the first round of comparison, 12<42, so the value of prev after the first round is 42 and returned. After that, the maximum value is 73.

3. Eliminate duplication

reduce can also be used to remove duplicate elements from an array

var arr = [12, 42, 12, 61, 73, 12, 42, 13, 19]
var result = arr.reduce(function(prev, cur){
  prev.indexOf(cur) === -1 ? && prev.push(cur)
  return prev
},[])

console.log(result) // [12, 42, 61, 73, 13, 19]

The above provides that the initial value is an empty array. Each time it is judged whether the current element is in the array, if it is, no operation is performed, and the original array is returned. If not, the element is put into prev, and finally a non-duplicate array is obtained.

The same principle can also be used in strings to remove repeated characters in the string and obtain a new string without repeated characters.

var str = 'asdaadasfdsdfaderhrrtjsfb'
var result = str.split('').reduce(function(prev, cur) {
  prev += prev.indexOf(cur) === -1 ? cur : ''
  return prev
}, '')

console.log(result) // asdferhtjb

Of course, you can also achieve deduplication of object arrays

var goods = [{type: 'plate', No: 123}, {type: 'bowl', No: 321}, {type: 'plate', No: 123}]

var result = goods.reduce((prev, cur) => {
  if(!prev.some(item => item.No === cur.No)) {
    prev.push(cur)
  }
  return prev
}, [])

console.log(result) // [{type: plate, No: 123}, {type: bowl, No: 321}]

4. Find the number of times

Reduce can be used to calculate the previous traversal result and the next item. We can also find the number of times an element or character appears in an array or string. The following is an example of finding the number of times a character appears in a string.

var str = 'asfasdasghsfadasdfsdgasdafgsada'

var result = str.split('').reduce((prev, cur) => {
  prev[cur] ? prev[cur]++ : prev[cur] = 1
  return prev
}, {})

console.log(result) // {a: 9, s: 8, f: 4, d: 6, g: 3, h: 1, s: 8 }

Finding the number of occurrences of an element in an array is the same as above.

5. Type conversion

Array to object

var goods = [{type: 'plate', No: 123}, {type: 'bowl', No: 321}]

var result = goods.reduce((prev, cur) => {
  !prev[cur.No] && (prev[cur.No] = cur)
  return prev
}, {})

console.log(result ) // {123: {type: "plate", No: 123}, 321: {type: "bowl", No: 321}}

Object to array

var obj = {123: {type: "plate", No: 123}, 321: {type: "bowl", No: 321}}

var result = Object.keys(obj).reduce((prev, cur) => {
  prev.push(obj[cur])
  return prev
}, [])

console.log(result) // [{type: "plate", No: 123}, {type: "bowl", No: 321}}]

Of course, this seems a bit tasteless, but here it just states that it has the ability to achieve this.


OK, here we are basically familiar with the commonly used uses of reduce as listed above. In fact, as long as we learn to adapt, we can also develop more usage skills. It is just a matter of cost and the quality of the method. JS is ever-changing. , we can have more choices.

The following is my public account, which is dedicated to pushing some summaries and other knowledge on the front end. If you are interested, please pay attention.

"Rookie Notes" public account

Guess you like

Origin blog.csdn.net/HU_YEWEN/article/details/117288155