我如何编写自己的`reduce`函数?

时间:2016-10-31 20:34:31

标签: javascript

我想自己写reduce。但是在过去的4个小时里,我无法做到。

var a = [10, 21, 13, 56];

function add(a, b) { return a + b }
function foo(a, b) { return a.concat(b) }

Array.prototype.reduce2 = function () {
  // I do not understand how to handle the function of the inlet
  // I know that I should use arguments, but I don't know how many arguments there will be
  var result = 0;
  for(var i = 0; i < arguments.length; i++) {
    result += arguments[i];
  }
 return result;
};

console.log(a.reduce(add), a.reduce2(add))         // 100 100
console.log(a.reduce(add, 10), a.reduce2(add, 10)) // 110 110

是的,我知道这似乎有很多主题,但我无法找到答案。我错过了什么,或者在这里做错了什么?

9 个答案:

答案 0 :(得分:5)

主题中的数组不作为参数传递,而是上下文(this)。

您还需要区分起始值的存在与否:

var a = [10, 21, 13, 56];

function add(a, b) { return a + b }
function foo(a, b) { return a.concat(b) }

Array.prototype.reduce2 = function (f, result) {
  var i = 0;
  if (arguments.length < 2) {
    i = 1;
    result = this[0];
  }
  for(; i < this.length; i++) {
    result = f(result, this[i], i, this);
  }
  return result;
};
console.log(a.reduce(add), a.reduce2(add))         // 100 100
console.log(a.reduce(add, 10), a.reduce2(add, 10)) // 110 110
// extra test with foo:
console.log(a.reduce(foo, 'X'), a.reduce2(foo, 'X')) // X10211356 X10211356

答案 1 :(得分:1)

根据您的代码

&#13;
&#13;
var a = [10, 21, 13, 56];

function add(a, b) { return a + b }
function foo(a, b) { return a.concat(b) }

Array.prototype.reduce2 = function(fn, start){
  var result = start !== undefined ? start : this[0];
  for (var i = 0; i < this.length; i++) {
    result = fn(result, this[i]);
  }
  return result;
};
console.log(a.reduce(add), a.reduce2(add))         // 100 100
console.log(a.reduce(add, 10), a.reduce2(add, 10)) // 110 110
console.log(a.reduce(foo, ''), a.reduce2(foo, ''));
console.log(a.reduce(foo, 'X'), a.reduce2(foo, 'X'));
&#13;
&#13;
&#13;

答案 2 :(得分:0)

我不确定我的答案是否能正确回答问题,但是我希望这可以对某人有所帮助。

不使用原型和循环的示例:

const origArr = [2,2]
const origFunc = (p,c) => p+c
const initial = 1

const reduce = (func, array, initial) => {
  const rec = (arr, acc) => {
    // arr: [2, 2], [2], []
    // acc: 1, 3, 5
    if (!arr.length) return acc
    const curr = arr[0]
    const nextArr = arr.slice(1)
    const nextAcc = func(acc, curr)
    return rec(nextArr, nextAcc)
  }
  if (initial) {
    return rec(array, initial)
  }
  return rec(array.slice(1), array[0])
}

console.log(origArr.reduce(origFunc, initial)) // 5
console.log(reduce(origFunc, origArr, initial)) // 5

还有循环示例:

const reduceLoop = (func, array, initial) => {
    let acc = initial !== undefined ? initial : array[0]
    let arr = initial !== undefined ? [initial, ...array] : array
    for(let i=1;i<arr.length;i++) {
      acc = func(acc, arr[i])
    }
    return acc
}

如您所见,在第一个示例中,我们没有分配变量,只有一些常量,但是在有循环的示例中,我们分配了tha acc变量。

答案 3 :(得分:0)

下面的代码将传递的数组减小为单个值。需要传递一个函数,该函数必须在数组上执行什么操作,并在需要时传递初始值。

Array.prototype.myFunction = function(fn,initial) {
    let arayEl = this;
    console.log(arayEl);
    let total = initial || 0;
    for(let i=0;i<arayEl.length;i++) {
        total = fn(total,arayEl[i]);
    }
    return total;
}

console.log([1,2,3].myFunction(function(total,x){return total +x},10));
console.log([1,2,3].reduce(function(total,x){return total +x},10));
console.log([1,2,3].myFunction(function(total,x){return total * x},10));
console.log([1,2,3].reduce(function(total,x){return total * x},10));
  • myFunction 是自定义的reduce函数,它接受回调函数(fn)和可选的初始值。它将像减速器一样工作。
  • 回调函数将函数(合计,x){return total + x}作为参数传递给myFunction,然后将其减小为单个值。在这里,我们可以执行与reduce相同的任何操作,而不是添加。

答案 4 :(得分:0)

const reduceV1 = (list, cb, intial) => {
  let memo = intial;
  for (let i = 0; i < list.length; i++) {
    if (i === 0 && memo === undefined) {
      memo = list[0];
    } else {
      memo = cb(list[i], memo);
    }
  }

  return memo;
};

function sumV1(n, sum) {
  return n + sum;
}

console.log(reduceV1([1, 2], sumV1));
console.log(reduceV1([1, 2,3], sumV1,0));

答案 5 :(得分:0)

var a = [10, 21, 13, 56];

function add(a, b) { return a + b }

Array.prototype.reduce2 = function(fn, start){
  var result = start !== undefined ? start : this[0];
  for (var i = 1; i < this.length; i++) {
    result = fn(result, this[i]);
  }
  return result;
};
console.log(a.reduce(add), a.reduce2(add))  

答案 6 :(得分:0)

实际减少功能:

const list = [1,2,3,4,5];
const sum = list => list.reduce((total, val)=> total+val, 0)
console.log(sum(list));

如果仔细观察,我们需要三件事:要迭代的列表,初始值和reduce函数

const reduceHelper = (list, initialValue, reducer) => {
// If the list is empty we will just return initial value
  if(list.length === 0) {
    return initialValue;
  } else {
    const [first, ...rest] = list;
    const updatedAcc = reducer(initialValue, first);
    return reduceHelper(rest, updatedAcc, reducer);
  }
}
// test it 
const list = [1,2,3,4,5];
console.log( myReduce(list, 0, (total, val) => total + val))

想法是一样的。我们可以遵循相同的想法,并编写不同的reduce函数来计数单词。......

答案 7 :(得分:0)

ownedItemCopy[index]

答案 8 :(得分:0)

使用 ES6 默认参数:

const nums = [1, 5, 5, 9];

Array.prototype.customReduce = function (callback, initial=0) {
  let result = initial;
  for (let i = 0; i < this.length; i++) {
    result = callback(result, this[i]);
  }
  return result;
};

const sum = nums.customReduce((acc, value) => acc + value, 0);
console.log(sum); // 20