JavaScriptjs数组中的map,filter, reduce, find, some, every方法的实现原理

JavaScriptjs数组中的map,filter, reduce, find, some, every方法的实现原理

map的用法和实现原理

用法

"map"即"映射",也就是原数组被"映射"成对应新数组。

let arr = [1,2,3];
arr1 = arr.map(item => item * 2)

实现原理

Array.prototype._map = function (callback) {
let newArr = [];
for (let i = 0; i < this.length; i++) {
  newArr.push(callback && callback(this[i]))
}
 return newArr
}
let result = [1,2,3]._map(item => item + 1)
console.log(result);  //[2, 3, 4]

filter的用法和实现原理

用法

过滤

let arr=[2,4,6,8];
let arr1=arr.filter(function(item){
    return item>5
})
console.log(arr1) //[6,8]

实现原理

Array.prototype._filter = function (callback) {
let newArr = [];
for (let i = 0; i < this.length; i++) {
  callback && callback(this[i], i) && newArr.push(this[i])
}
return newArr
}

let filter = [1,2,3]._filter(item => item > 1) 
console.log(filter); // [2,3]

find的用法和实现原理

用法

该方法返回通过测试的数组的第一个元素的值

let arr=[2,4,6,8];
let arr1=arr.find(function(item){
    return item>5
})
console.log(arr1) // 6

实现原理

Array.prototype._find = function (callback) {
    let currentVal
    for (let i = 0; i <this.length; i++) {
      if (callback(this[i])) {
        currentVal = this[i]
        break
      }
    }
    return currentVal
}
let result = [1,2,3,4]._find(item => item > 1)
console.log(result);  // 2

reduce的用法和实现原理

用法

累加

let arr=[2,4,6,8];
let arr1=arr.reduce((prev, item) => prev + item, 0)
console.log(arr1) // 20

实现原理

Array.prototype._reduce = function (callback, initVal) {
    for (let i = 0; i < this.length; i++) {
      initVal = callback(initVal, this[i], i, this)
    }
    return initVal
}
let result = [1,2,3,4]._reduce((prev, item) => prev + item, 0)
console.log(result);  // 10

some的用法和实现原理

用法

只要有一个元素满足条件就返回true

let arr = [1,2,3,4];
let res = arr.some(item => item > 4)
console.log(res);   // false

实现原理

Array.prototype._some = function (callback) {
// callback &&
let result = false
for (let i = 0; i < this.length; i++) {
  result = callback && callback(this[i])
}
return result
}
let result = [1,2,3]._some(item => item > 1)
console.log(result);  // true

every的用法和实现原理

用法

数组中每一个元素满足条件就返回true

let arr = [1,2,3,4];
let res = arr.every(item => item > 0)
console.log(res);   // true

实现原理

Array.prototype._every = function (callback) {
let result = true
for (let i = 0; i < this.length; i++) {
  if(!callback(this[i])) {
    result = false
    break
  }
}
return result
}
let result = [1,2,3]._every(item => item > 0)
console.log(result);  //true
let result = [1,2,3]._every(item => item > 1)
console.log(result);  //false

reduce实现filter,map 数组扁平化等

map 函数接收一个函数作为参数,作为参数的函数接收三个参数值,分别是遍历数组的每一项元素,元素的索引和数组本身。这三个参数刚好和reduce函数接收的第一个函数参数的第2、3、4个参数是对应的。这是实现的核心
实现思路是,将每次遍历的元素,作为传入的函数的参数,并将函数执行的结果放入新的数组中。

reduce实现map

Array.prototype._map = function (callback) {
  if(typeof callback === 'function') {
    return this.reduce((prev,item,index,arr) => {
      prev.push(callback(item, index, arr))
      return prev
    }, [])
  } else {
    console.log(new Error('callback is not function'))
  }
}

let val = [1, 5, 6]._map(item => item+ 1)
console.log(val);  // [2, 6, 7]

复制代码实现filter的思路和实现map是一致的,只不过前者是一股脑的把执行结果全放入数组中,而filter需要做一个判断:如果filter函数传入的参数(参数是一个函数)执行后有返回值,即经过了检验,才将遍历的当前元素放入数组中,如果没有返回值,就忽略

reduce实现filter

  Array.prototype._filter = function (callback) {
    if(typeof callback === 'function') {
      return this.reduce((prev,item,index,arr) => {
        callback(item, index, arr) ? prev.push(item) : null
        return prev
      }, [])
    } else {
      console.log(new Error('callback is not function'))
    }
  }
  let val = [1, 5, 6]._filter(item => item > 2)
  console.log(val);  // [5, 6]

求最大值/最小值

let arr = [1, 2, 3, 4, 5]

console.log(arr.reduce((prev, cur) => Math.max(prev, cur))); // 5

console.log(arr.reduce((prev, cur) => Math.min(prev, cur))); // 1

数组去重

let arr = [1, 2, 3, 1, 1, 2, 3, 3, 4, 3, 4, 5]

let result = arr.reduce((prev, item, index, arr) => {
!prev.includes(item) && prev.push(item);
return prev
}, [])
console.log(result);  //[1, 2, 3, 4, 5]

数组扁平化

let arr = [1, 2, '3js', [4, 5, [6], [7, 8, [9, 10, 11], null, 'abc'], {age: 58}, [13, 14]], '[]', null];
function f(arr) {
    if(Array.isArray(arr)) {
      return arr.reduce((prev, item) => {
        return Array.isArray(item) ? prev.concat(f(item)) : prev.concat(item)
      }, [])
    } else {
      throw new Error("arr + ' is not array'")
    }
}