数组的总和-JavaScript

时间:2019-06-24 14:57:26

标签: javascript arrays sum reduce

尝试解决this challenge on codewars。根据挑战,数组的各个部分:

ls = [0, 1, 3, 6, 10]

ls = [0, 1, 3, 6, 10]
ls = [1, 3, 6, 10]
ls = [3, 6, 10]
ls = [6, 10]
ls = [10]
ls = []

我们需要返回一个包含这些部分之和的数组。

所以我的代码如下:

function partsSums(ls) {
  let arrayOfSums = []; 
  while(ls.length > 0) {
    let sum = ls.reduce((a, b) => a + b);
    arrayOfSums.push(sum);
    ls.shift();
  }
return arrayOfSums;
}

console.log(partsSums([0, 1, 3, 6, 10]));

问题在于,它希望我们在数组为空时将最后一个总和0加。所以我们应该得到:

  

[20,20,19,16,10,0]

代替

  

[20,20,19,16,10]

所以我尝试了这个:

function partsSums(ls) {
  let arrayOfSums = []; 
  while(ls.length > 0) {
    let sum = ls.reduce((a, b) => a + b);
    arrayOfSums.push(sum);
    ls.shift();
  }
arrayOfSums.push(0);
return arrayOfSums;
}
console.log(partsSums([0, 1, 3, 6, 10]));

这:

function partsSums(ls) {
  ls.push(0);
  let arrayOfSums = []; 
  while(ls.length > 0) {
    let sum = ls.reduce((a, b) => a + b);
    arrayOfSums.push(sum);
    ls.shift();
  }
return arrayOfSums;
}

但这会导致Codewar上的执行超时错误:

  

执行超时(12000毫秒)

所以我也尝试过:

function partsSums(ls) {
  let arrayOfSums = []; 
  while(ls.length > -1) {
    let sum = ls.reduce((a, b) => a + b);
    arrayOfSums.push(sum);
    ls.shift();
  }
return arrayOfSums;
}

但是现在这会导致TypeError:

  

TypeError:减少没有初始值的空数组

我不理解在将所有值都移出后如何将0放入数组的概念。即使数组为空,挑战似乎也想将0作为数组的最终“和”。但是您不能减少一个空数组-在这里我还能做什么?

编辑:尝试将初始值添加到reduce方法:

function partsSums(ls) {
  let arrayOfSums = []; 
  while(ls.length > 0) {
    let sum = ls.reduce((a, b) => a + b, 0);
    arrayOfSums.push(sum);
    ls.shift();
  }
return arrayOfSums;
}

不幸的是,这仍然未能通过基本测试:

  

期望[]等于[0]

6 个答案:

答案 0 :(得分:10)

没有理由一遍又一遍地计算总和。在长数组上,这将是非常低效的(O(n²)),并可能解释您的超时错误。首先计算总和,然后从循环中减去每个元素。

ls = [0, 1, 3, 6, 10]

function partsSums(ls) {
    let sum = ls.reduce((sum, n) => sum + n, 0)
    res  = [sum]
    for (let i = 1; i <= ls.length; i++){
        sum -= ls[i-1]
        res.push(sum )
    }
    return res
}
console.log(partsSums(ls))

答案 1 :(得分:4)

另一个通过所有测试的解决方案:

function partsSums(ls) {
    let result = [0],
      l = ls.length - 1;
      
    for (let i = l; i >= 0; i--) {
        result.push(ls[i] + result[ l - i]);
    }
    return result.reverse();
}


console.log(partsSums([]));
console.log(partsSums([0, 1, 3, 6, 10])); 
console.log(partsSums([1, 2, 3, 4, 5, 6]));
console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));

答案 2 :(得分:1)

您可以将forslice一起使用,当i == 0可以切片len + 1时,它将返回空数组,总和为0。

function partsSums(arr) {
  const res = [], len = arr.length
  for (let i = len; i > -1; i--) {
    res.push(arr.slice(-i || len + 1).reduce((a, n) => a + n, 0))
  }
  return res;
}

console.log(partsSums([0, 1, 3, 6, 10]));
console.log(partsSums([1, 2, 3, 4, 5, 6]));
console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));

您还可以使用两个双reduce,如果没有下一个元素,则按0。

function partsSums(arr) {
  const sum = arr => arr.reduce((r, e) => r + e, 0);
  return arr.reduce((r, e, i, a) => {
    const res = sum(a.slice(i, a.length));
    return r.concat(!a[i + 1] ? [res, 0] : res)
  }, [])
}

console.log(partsSums([0, 1, 3, 6, 10]));
console.log(partsSums([1, 2, 3, 4, 5, 6]));
console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));

答案 3 :(得分:1)

您可以从末尾进行迭代,并取该值加上结果集的最后插入值。

这种方法仅适用于单个循环,而无需事先计算最大和。

function partsSums(ls) {
  var result = [0],
      i = ls.length;
      
  while (i--) {
      result.unshift(ls[i] + result[0]);
  }
  return result;
}

console.log(partsSums([0, 1, 3, 6, 10]));
console.log(partsSums([]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

使用pushreverse

function partsSums(ls) {
  var result = [0],
      l = 0,
      i = ls.length;
      
  while (i--) result.push(l += ls[i]);
  return result.reverse();
}

console.log(partsSums([0, 1, 3, 6, 10]));
console.log(partsSums([]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 4 :(得分:1)

尝试递归:

function partsSums(ls) {
  let sum = ls.reduce((a, b) => a + b, 0);
  return  ls.length > 0 ? [sum].concat(partsSums(ls.slice(1))) : [0];
}

console.log(partsSums([0, 1, 3, 6, 10]));
console.log(partsSums([1, 2, 3, 4, 5, 6]));
console.log(partsSums([744125, 935, 407, 454, 430, 90, 144, 6710213, 889, 810, 2579358]));

答案 5 :(得分:1)

这是你可以做的一件事

function partsSums(ls) {
  if(!ls.length) return [0];
  let prevTotal = ls.reduce((a,b) => a + b);
  return [prevTotal, ...ls.map(val => prevTotal -= val)]
}

console.log(partsSums([0, 1, 3, 6, 10]));