what
首先我们需要理解reduce这个方法的语法:
arr.reduce(callback,init)
arr.reduce((prev,cur,index,arr)={
...
},[])
* callback (执行数组中每个值的函数,包含四个参数)
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
* init (作为第一次调用 callback 的第一个参数。)
其中: callback:reduce为数组中每一个元素依稀执行回调函数,不包括数组中被删除或从未赋值的元素。 callback 接受四个参数:prev 初始值(或者上一次回调函数的返回值),cur 当前索引值,index 当前索引,arr 调用reduce的数组。
实现:
简单方法
reduce进行数组求和
var arr = [1,2,3,4];
var sum = arr.reduce((prev,cur)=>{
return prev + cur;
},0)
console.log(sum)
reduce求数组项的最大值
var arr = [1,2,3,4,6];
var max = arr.reduce((prev,cur)=>{
return Math.max(prev,cur)
},0)
console.log(max)
进阶:
数组去重 使用includes判断数组是否包含当前元素
var arr = [1,2,3,4,6,1,2,3];
var newArr = arr.reduce((prev,cur)=>{
if(!prev.includes(cur)){
return prev.concat(cur)
}else{
return prev
}
},[])
console.log(newArr)
计算数组中每个元素出现的个数
这里我们用了in 关键字,来判断对象是否包含某个属性,会返回 true/false 也可以使用hasOwnProperty 该方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性,会返回 true/false
let names = ['Alice', 'Bob','Alice', 'Tiff', 'Bruce', 'Alice'];
var result = names.reduce((prev,cur)=>{
if(cur in prev){
prev[cur]++
}else{
prev[cur] = 1
}
return prev
},{})
console.log(result)
reduce 实现扁平化
(当然我们也可以使用ES6 的 flat 实现数组扁平化,不过面试的时候面试官说不定会让你手写哦)
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log(newArr)
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
function fn(arr){
return arr.reduce((prev,cur)=>{
return prev.concat(Array.isArray(cur) ? fn(cur) : cur)
},[])
}
console.log(fn(arr))
面试题
了解并熟练掌握reduce的使用,我们来看一下今天最终要实现的 map
题目:用数组的reduce方法实现map方法
面试题目,用数组的reduce方法实现map方法,是需要使用reduce来达到模拟map效果,那么也应该满足map这个方法里面参数问题
而下面这个题目的意思则是需要写出来一个函数,使得函数实现一个map功能, 仅此而已
题目 arr = [1,2,3] a.xmap(i => i *2) // [2,4,6 ]
map相关概念: 遍历数组的每一项,并执行回调函数的操作,返回一个对每一项进行操作后的新数组
let array = arr.map(function callback(currentValue, index, array) {
...
}[, thisArg])
参数含义: 1、callback 生成新数组元素的函数,使用三个参数:
- currentValue :数组中正在处理的当前元素
- index :数组中正在处理的当前元素的索引
- array:map方法被调用的数组
2、thisArg 可选的。执行 callback 函数时 使用的this 值。
const xmap = function(arr,fn){
return arr.reduce((pre,cur)=>{
return [...pre,fn(cur)]
},[])
}
const arr = [1,2,3]
console.log(xmap(arr,i=>i*2))
然后我们来看上面两个题对应的解答:
一、使用reduce实现数组map方法
原生map方法的特点: 1、map不会对原数组产生影响 2、map返回的是一个新数组 3、一个数组一旦调用map方法,每一个元素都会执行map中的回调函数。 4、map方法会跳过被delete删除或者未定义的元素 第一个参数:callback map接收的第一个参数是一个回调函数,这个参数是必须传入的,callback中有三个可选参数,分别代表着元素,索引和调用map方法的数组,也就是(item,index,arr)。 第二个参数:thisArg(定义执行callback的this指向):可选 第二个参数表示的是callback的this指向。
Array.prototype.myMap = function(fn,thisArg = []){
if(typeof fn != 'function'){
throw new Error(`${fn} is not a function`);
}
return this.reduce((pre,cur,index,arr) => {
return pre.concat(fn.call(thisArg,cur,index,arr));
},[])
}
const arr = [2,3,1,5];
const temp = arr.myMap(item => item * 2);
console.log(temp);
二、简单实现处理数组功能
const xmap = function(arr,fn){
return arr.reduce((pre,cur)=>{
return [...pre,fn(cur)]
},[])
}
const arr = [2,4,5,6]
console.log(xmap(arr,n => n * 2))
|