JS中的reduce用法详解

782 阅读3分钟

普通数组去重

第一种使用for循环

var arr = [1, 3, 4, 4, 5, 3, 3, 7]
// 使用for循环
var newArr = []
for (let i = 0; i < arr.length; i++) {
  if (newArr.indexOf(arr[i]) === -1) { // 简单易懂。但是这里不能直接使用newArr.indexOf(arr[i])来判断。单独的是-1,取反是true
    newArr.push(arr[i])
  }
}
console.log(newArr)

上面的就等价于

var arr = [1, 3, 4, 4, 5, 3, 3, 7]
// 使用for循环
var newArr = []
for (let i = 0; i < arr.length; i++) {
  newArr.indexOf(arr[i]) === -1 && newArr.push(arr[i]) // 这样写的方式更简单一些。省去了if判断
}
console.log(newArr)

解题思路:

  1. 先声明一个空的数组,用来存放新生成的去重之后的数组
  2. 使用循环,先使用indexOf里面有没有第i个元素,没有是-1,然后push到新数组
  3. 这里使用for循环不需要有返回值。不支持,需要全局声明一个变量。

第二种使用forEach循环

var arr = [1, 3, 4, 4, 5, 3, 3, 7]
var newArr = []
arr.forEach(item => {
  newArr.indexOf(item) === -1 && newArr.push(item)
})
console.log(newArr)

第三种使用reduce

var arr = [1, 3, 4, 4, 5, 3, 3, 7]
var newArr = arr.reduce((pre,next)=>{
  pre.indexOf(next) === -1 && pre.push(next)
  return pre
},[]) // 这里使用reduce,初始化的时候是一个空的数组
console.log(newArr)

① 初始化一个空数组 ② 将需要去重处理的数组中的第1项在初始化数组中查找,如果找不到(空数组中肯定找不到),就将该项添加到初始化数组中 ③ 将需要去重处理的数组中的第2项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中 ④ …… ⑤ 将需要去重处理的数组中的第n项在初始化数组中查找,如果找不到,就将该项继续添加到初始化数组中 ⑥ 将这个初始化数组返回

第四种使用filter

var arr = [1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4]
  var newArr = []
  newArr = arr.filter(function (item) {
    return newArr.includes(item) ? '' : newArr.push(item)
  })
console.log(newArr);
// 结果是[1, 2, 3, 5, 6, 7, 4]
// 这里使用indexOf
var newArr = []
  newArr = arr.filter((item)=>{
    return newArr.indexOf(item) === -1 ? newArr.push(item) : ''
  })

数组对象去重

let person = [
     {id: 0, name: "aaa"},
     {id: 1, name: "bbb"},
     {id: 2, name: "ccc"},
     {id: 3, name: "ddd"},
     {id: 1, name: "eee"},
     {id: 2, name: "fff"},   
];
 
let obj = {};//有助于增加遍历效率
 
person = person.reduce((cur,next) => {
    obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
    return cur;
},[]) //设置cur默认类型为数组,并且初始值为空的数组
console.log(person);

数组求和

第一种使用forEach

var arr = [1,2,3]
var sum1 = 0; // 必须要在外面写成sum1 = 0,不然sum1的结果是一个NaN
arr.forEach(item => sum1+=item)
console.log(sum1)

第二种使用for循环

var arr = [1,2,3]
let sum2 = 0; // 必须要在外面写成sum2 = 0,不然sum2的结果是一个NaN
for (let i = 0; i < arr.length; i++) {
  sum2 += arr[i]
}
console.log(sum2)

第三种使用reduce

var arr = [1, 2, 3]
let result = arr.reduce((pre, next) => {
  return pre + next
},0)

console.log(result)
// 上面的给了一个初始化的值,0.当数组为空时不报错。但是不给初始值,就会出现下面这种情况
var  arr = [];
var sum = arr.reduce(function(prev, cur, index, arr) {
    console.log(prev, cur, index);
    return prev + cur;
})
//报错,"TypeError: Reduce of empty array with no initial value"

数组内元素出现的次数

这个和数组元素如果出现了一次以上就是true,否则是false类似

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

let nameNum = names.reduce((pre,cur)=>{
  if(cur in pre){
    pre[cur]++
  }else{
    pre[cur] = 1 
  }
  return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

// 等价于
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

let nameNum = names.reduce((pre,cur)=>{
  cur in pre ? pre[cur]++ : pre[cur] = 1
  return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

// 封装成方法
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
function nameNum(names) {
  return names.reduce((pre, cur) => {
    console.log(pre, cur)
    if (cur in pre) {
      pre[cur]++
    } else {
      pre[cur] = 1
    }
    return pre
  }, {})
}
console.log(nameNum(names)); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
// 等价于
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
function nameNum(names) {
  return names.reduce((pre, cur) => {
    cur in pre ? pre[cur]++ : pre[cur] = 1
    return pre
  }, {})
}
console.log(nameNum(names)); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}

数组元素如果出现了一次以上就是true,否则是false类似

let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']
function dupicaltedWord (names) {
  return foo = names.reduce((pre, next) => {
    next in pre ? pre[next] = 'true' : pre[next] = 'false'
    return pre
  }, {})
}
console.log(dupicaltedWord(names))

二维数组转成一维数组=数组扁平化

let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
    return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]

多维数组转成一维数组=数组扁平化

let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
   return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]

数组对象求和

var result = [
    {
        subject: 'math',
        score: 10
    },
    {
        subject: 'chinese',
        score: 20
    },
    {
        subject: 'english',
        score: 30
    }
];

var sum = result.reduce(function(prev, cur) {
    return cur.score + prev;
}, 0);
console.log(sum) //60

数组最大值

const a = [23,123,342,12];
const max = a.reduce(function(pre,cur,inde,arr){return pre>cur?pre:cur;}); // 342

数组最小值

const a = [23,123,342,12];
const min = a.reduce(function(pre,cur,inde,arr){return pre>cur?cur:pre;}); // 12