[Learning Record 18] Learning map and reduce

map() 

map()method creates a new array whose result is that each element in the array is the return value of one call to the provided function. It's a bit convoluted, so let's go directly to the example.

const array1 = [1, 4, 9, 16];

// 数组中的每个数都乘以2
const map1 = array1.map(x => x * 2);
console.log(map1);
// 输出结果:数组 [2, 8, 18, 32];

// 如果是计算平方
const map2 = array1.map(x => x * x);
console.log(map2);
// 输出结果:数组 [1, 16, 81, 256];

// 也可以这样计算平方根
const  map3 = numbers.map(Math.sqrt);
console.log(map3);
// 输出结果:数组 [1, 2, 3, 4];

reduce()

reduce()method executes a reducer function provided by you (in ascending order) for each element in the array , aggregating its results into a single return value. This one is more difficult to understand. . . Or go straight to the example.

const array1 = [1, 2, 3, 4];
const reducer = (previousValue, currentValue) => previousValue + currentValue;

// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// 输出: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// 输出: 15

The reducer  function receives 4 parameters:

  1. Accumulator (acc) (accumulator)
  2. Current Value (cur) (current value)
  3. Current Index (idx) (current index)
  4. Source Array (src) (source array)

The return value of your  reducer  function is assigned to the accumulator, which is remembered on each iteration of the array and finally becomes the final single result value.

How reduce() works

If you run the following reduce()code:

[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
  return accumulator + currentValue;
});

callback is called four times, and the parameters and return values ​​of each call are as follows:

callback accumulator(累计数) currentValue(当前值) currentIndex(下标) array(数组) return value
first call 0 1 1 [0, 1, 2, 3, 4] 1
second call 1 2 2 [0, 1, 2, 3, 4] 3
third call 3 3 3 [0, 1, 2, 3, 4] 6
fourth call 6 4 4 [0, 1, 2, 3, 4] 10

The value returned by reducewill be the last callback return value (10).

You can also use arrow functions instead of full functions. The code below will produce the same output as the code above:

[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );

If you intend to provide an initial value as reduce()the second parameter of the method, the following is the operation process and results:

[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => {
    return accumulator + currentValue
}, 10)

callback accumulator(累计数) currentValue(当前值) currentIndex(下标) array(数组) return value
first call 10 0 0 [0, 1, 2, 3, 4] 10
second call 10 1 1 [0, 1, 2, 3, 4] 11
third call 11 2 2 [0, 1, 2, 3, 4] 13
fourth call 13 3 3 [0, 1, 2, 3, 4] 16
fifth call 16 4 4 [0, 1, 2, 3, 4] 20

reduce()The value returned in this case is 20.

reduce example

the sum of all values ​​in the array

var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);
// 和为 6

You can also write it as an arrow function:

var total = [ 0, 1, 2, 3 ].reduce(
  ( acc, cur ) => acc + cur,
  0
);

Accumulates values ​​in an array of objects

To accumulate the values ​​contained in an object array, an initial value must be provided so that the individual items pass through your function correctly.

var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
},initialValue)

console.log(sum) // logs 6

You can also write it as an arrow function:

var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(
    (accumulator, currentValue) => accumulator + currentValue.x
    ,initialValue
);

console.log(sum) // logs 6

Convert two-dimensional array to one-dimensional

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  function(a, b) {
    return a.concat(b);
  },
  []
);
// flattened is [0, 1, 2, 3, 4, 5]

You can also write it as an arrow function:

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
 ( acc, cur ) => acc.concat(cur),
 []
);

Count the number of occurrences of each element in an array

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

var countedNames = names.reduce(function (allNames, name) {
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

Classify objects by attributes

var people = [
  { name: 'Alice', age: 21 },
  { name: 'Max', age: 20 },
  { name: 'Jane', age: 20 }
];

function groupBy(objectArray, property) {
  return objectArray.reduce(function (acc, obj) {
    var key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

var groupedPeople = groupBy(people, 'age');
// groupedPeople is:
// {
//   20: [
//     { name: 'Max', age: 20 },
//     { name: 'Jane', age: 20 }
//   ],
//   21: [{ name: 'Alice', age: 21 }]
// }

Binding an array contained within an array of objects using the spread operator and initialValue

// friends - 对象数组
// where object field "books" - list of favorite books
var friends = [{
  name: 'Anna',
  books: ['Bible', 'Harry Potter'],
  age: 21
}, {
  name: 'Bob',
  books: ['War and peace', 'Romeo and Juliet'],
  age: 26
}, {
  name: 'Alice',
  books: ['The Lord of the Rings', 'The Shining'],
  age: 18
}];

// allbooks - list which will contain all friends' books +
// additional list contained in initialValue
var allbooks = friends.reduce(function(prev, curr) {
  return [...prev, ...curr.books];
}, ['Alphabet']);

// allbooks = [
//   'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
//   'Romeo and Juliet', 'The Lord of the Rings',
//   'The Shining'
// ]

Array deduplication

 Note: If you are using an environment compatible with Set  and  Array.from()let orderedArray = Array.from(new Set(myArray)); , you can use  to get an array with identical elements removed.

let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
let myOrderedArray = myArray.reduce(function (accumulator, currentValue) {
  if (accumulator.indexOf(currentValue) === -1) {
    accumulator.push(currentValue)
  }
  return accumulator
}, [])

console.log(myOrderedArray) //  ['a', 'b', 'c', 'e', 'd']

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current) => {
    if(init.length === 0 || init[init.length-1] !== current) {
        init.push(current);
    }
    return init;
}, []);
console.log(result); //[1,2,3,4,5]

Related link:


MDN reduce

Liao Xuefeng's official website - map/reduce

Guess you like

Origin blog.csdn.net/wenhui6/article/details/122860692