xiaohesong / TIL

本库记录每日所学,README是一些链接;学习是自己的事。
http://t.cn/EP1BKKb
297 stars 67 forks source link

reduce: 实现一个reduce方法 #18

Open xiaohesong opened 5 years ago

xiaohesong commented 5 years ago

今天无意间看到一个面试题有问到如何实现一个reduce函数,额,花了点时间算是写下来了。写这个方法的前提是了解这个api。

所以,reduce函数的第一个参数(函数)的第三个参数(索引), 就是根据reduce函数的第二个参数在数组中的牵引做的判断。

好了,我们知道了这个reduce函数的api之后,我们尝试来写个:

const array = [11, 22, 33]
const reducer = (arr, fn, initValue) => {
  if(!Array.isArray(arr)) throw new Error('First Argument Must Be Array')
  if(typeof fn !== 'function') throw new Error('Second Argument Must Be Function');

  var i = initValue ? 0 : 1 // 因为如果不存在initValue, 数组第一个就得补上,所以索引从1开始。和下面的赋值操作的顺序不可以对调!
  initValue = initValue ? initValue : arr[0] //因为存在init的话,第一个就是init, 不存在,第一个就是数组的第一个元素
  for(i; i < arr.length; i++){
    initValue = fn(initValue, arr[i], i, arr)
  }

  return initValue
} 
reducer(array, (sum, i) => sum + i)
terrywangt commented 5 years ago
//1.reduce
Array.prototype.myReduce = function (fn, prev) {
  for (let i = 0; i < this.length; i++) {
    if (typeof prev === 'undefined') {
      prev = fn(this[i], this[i + 1], i + 1, this);
      ++i; 
    } else {
      prev = fn(prev, this[i], i, this);
    }
  }
  return prev;
}
let total = [1, 2, 3].myReduce((prev, next, currIndex, ary) => {
  return prev + next
}, 0);
console.log(total);

let flat = [[1, 2, 3], [4, 5, 6]].reduce((prev, next, index, ary) => {
  return [...prev, ...next];
});
console.log(flat);
// 2) forEach
Array.prototype.forEach = function (fn) {
  for (let i = 0; i < this.length; i++) {
    fn(this[i], i);
  }
}
  ;[1, 2, 3].forEach((item, index) => {
    console.log(item, index);
  })
// 3.map
Array.prototype.map = function (fn) {
  let arr = [];
  for (let i = 0; i < this.length; i++) {
    arr.push(fn(this[i], i));
  }
  return arr;
};
let arr = [1, 2, 3].map(item => {
  return item * 2;
});
console.log(arr);
xiaohesong commented 5 years ago

@terrywangt 不错哦,给你高亮显示了。之前reduce也是循环判断,最后换成了先初始化 😃