关于数组归约函数中的初始起始值的问题

时间:2019-06-14 21:30:09

标签: javascript arrays reduce

我实际上遇到了一个问题,更多有关此作业问题的说明如下:

将collection减少为一个值,该值是通过iteratee运行collection中的每个元素的累积结果, 向每个连续调用提供前一个的返回值。 如果未提供累加器,则集合的第一个元素将用作初始值。如果未提供起始参数,则将起始值设置为第零个索引。

这是应该发生的事情的细分:

// reduce([1,2], function(stored,current) {
//  return stored + current;
// }); → 3
// reduce([1,2], function(stored,current) {
//  return stored + current;
// },1); → 4

如果我正确阅读了说明,则start参数是开始累积的初始值,不是吗?如果在函数调用中未提供起始参数,则索引0处的值为起始值。唯一的问题是,在没有提供开始参数的情况下获取该值时,第一个val会被累加两次,这将返回一个意外的结果。

到目前为止,我已经研究了reduce方法和从不同索引开始的不同方法。 看起来好像没有提供起始值,我需要将初始值设置为array [0],然后将array.slice(1)并从那里减少,但是,我不确定这就是赋值所说的去做。

我不太了解if accumulator is not provided和if start parameter is not provided之间的区别。如果未提供累加器,则初始值是否不是输入数组中的第一个值,起始索引是否为1?这样就不会两次将第一个值相减?

这是我的代码:

function reduce(array, callback, start) { 
    return array.reduce((acc, val, start) => {
      //if start value not provided, start value is index 0
        return callback(acc, val) }, start || array[0])
}

这是结果。

//start provided as -1, result correct
var difference = function(tally, item) {return tally - item; };
var total = reduce([1, 2, 3], difference, -1); // expected -> -7 got -7

//start provded as 2, result correct
var add = function(tally, item) {return tally + item; };
var total = reduce([1, 2, 3], add, 2); // expected -> 8 got 8

//start not provided, first index used as start, as per instructions
//therefore first index is added twice, giving wrong answer
var add = function(tally, item) {return tally + item; };
var total = reduce([1, 2, 3], add); // expected -> 6 got 7

//start not provided, first index used as start, as per instructions
//therefore first index is subtracted twice, giving wrong answer
var difference = function(tally, item) { return tally - item; };
var total = reduce([1, 2, 3], difference); // -> expected -4 got -5

2 个答案:

答案 0 :(得分:0)

是的,您是对的。如果未提供初始累加器,则将第一个数组元素视为一个累加器,然后从第二个元素开始调用回调。

您的代码虽然将第一个数组元素作为累加器传递,但仍将其复制。同样在这里使用||是危险的,例如,它将失败。 0。我会做的:

 function reduce(array, callback, start) { 
   return array.reduce(callback, start);
 }

答案 1 :(得分:0)

使用reduce函数仅调用内置的reduce有点奇怪。如果目标是编写自己的reduce,那么如果您明确地进行循环,则可能会有些许困难。

基于是否给出start,您需要做出两个选择:累加器的初始值以及是否要开始对数组的第一项或第二项进行迭代:

function reduce(array, callback, start) { 
    let start_index = start ? 0 : 1                   // start iteration on second item if start not given
    let acc = start === undefined ? array[0] : start  // use array[0] if start not given

    for (let i = start_index; i < array.length; i++){
        acc  = callback(acc, array[i])
    }
    return acc
}
var add = function(tally, item) {return tally + item; };

var total = reduce([1, 2, 3], add); // expected -> 6 got 7
console.log(total) // 6 as expected

var difference = function(tally, item) { return tally - item; };
var total = reduce([1, 2, 3], difference); // -> expected -4 got -5
console.log(total)  // -4 as expected