Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce: 实现一个reduce方法 #18

Open
xiaohesong opened this issue Dec 28, 2018 · 2 comments
Open

reduce: 实现一个reduce方法 #18

xiaohesong opened this issue Dec 28, 2018 · 2 comments
Labels
function rewrite 重写一些原生方法

Comments

@xiaohesong
Copy link
Owner

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

  • 默认初始值
    这个就是对应的reduce的第二个参数。
    • 如果有这个参数,那么这个参数将作为reduce的第一个参数(函数)的第一个参数,(函数)的第二个参数是数组的第一个参数;
    • 如果没有这个,那么reduce函数的第一个参数(函数)的第一个参数是数组的第一个元素,(函数)的第二个参数就是数组的第二个元素。

所以,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)
@xiaohesong xiaohesong added rewrite 重写一些原生方法 function labels Dec 28, 2018
@terrywangt
Copy link

terrywangt commented Dec 29, 2018

//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
Copy link
Owner Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
function rewrite 重写一些原生方法
Projects
None yet
Development

No branches or pull requests

2 participants