所有参数的总和(某些参数是数组); sum([1,2,3,4],50,10,[10,20],1)

时间:2019-05-01 00:00:19

标签: javascript arrays optimization arguments reduce

我有一个function sum([1,2,3,4],50,10,[10, 20],1),它由整数和数组组成,并且我想要返回所有单个元素的总和。在给定的示例中,总和为101。

问题:我找到了一种可行的方法,但我想知道我可以做些什么来使其更高效。

我的方法如下:

  1. 初始化一个新数组 ;像数组[1,2,3,4]这样的数组参数将首先被转换为和,然后被推入新数组。
  2. 通过所有参数
  3. for循环
  4. 检查 (如果参数是数组)
    • 如果 ,则将所有元素加和到(通过.reduce(),然后将sum推入新数组。
    • 如果 ,则将元素推入新数组
  5. newArray转换为总和(再次通过.reduce()并返回。

代码:

console.log("Result: " + sum([1,2,3,4],50,10,[10, 20],1));

function sum(...allArgs) {

    let newArray = [];
    // go through all args
    allArgs.forEach((elem) => {
        // check if argument is an array
        if (Array.isArray(elem)){
            // arraySum = all Items of array 
            arraySum = elem.reduce((acc, currV) => acc + currV, 0);
            // push arraySum into new Array
            return newArray.push(arraySum);
        }
        // push other arguments (that are not arrays) into new array
        newArray.push(elem);
    });
    // return the sum of the new array
    return newArray.reduce((acc, currV) => acc + currV);
}

我发现了一个comparable post,不同之处在于,该帖子中没有参数是数组,因此是此帖子。

在此过程中我可以改善什么?

4 个答案:

答案 0 :(得分:2)

您可以将forEach替换为reduce

function sum(...allArgs) {

  // go through all args
  return allArgs.reduce((sum, elem) => {
      // check if argument is an array
      if (Array.isArray(elem)){
          // arraySum = all Items of array 
          return sum + elem.reduce((s,i)=>s+i,0);
      }else{
        return sum + elem;
      }
  },0);
}

sum([1,2,3],50,10,[10, 20],1)

或嵌套总和

function sum(...allArgs) {
  // go through all args
  return allArgs.reduce((total, elem) => {
    // check if argument is an array
    if (Array.isArray(elem)) {
      return total + sum(...elem);
    } else {
      return total + elem;
    }
  }, 0);
}

sum([1, 2, 3], 50, 10, [10, 20,[11,12]], 1);

答案 1 :(得分:2)

您可能喜欢的另一种方式-

const sum = (x, ...more) =>
  x === undefined
    ? 0                       // 1
    : Array.isArray(x)
        ? sum(...x, ...more)  // 2
        : x + sum(...more)    // 3

console.log(sum([1,2,3,4],50,10,[10, 20],1)) // 101

  1. 基本情况:x未定义–终止计算并返回空值0
  2. 归纳的情况:x not 未定义,而x是一个数组–返回xmore的价差之和
  3. 归纳的情况:x not 未定义,而x not 是数组–因此,x是单个元素。返回x more的总和。

铅笔和纸张评估-

该行末的编号注释与上面的编号代码路径相对应

sum([1,2,3,4],50,10,[10,20],1)                                  // 2
= sum(1,2,3,4,50,10,[10,20],1)                                  // 3
= 1 + sum(2,3,4,50,10,[10,20],1)                                // 3
= 1 + (2 + sum(3,4,50,10,[10,20],1))                            // 3
= 1 + (2 + (3 + sum(4,50,10,[10,20],1)))                        // 3
= 1 + (2 + (3 + (4 + sum(50,10,[10,20],1))))                    // 3
= 1 + (2 + (3 + (4 + (50 + sum(10,[10,20],1)))))                // 3
= 1 + (2 + (3 + (4 + (50 + (10 + sum([10,20],1))))))            // 2
= 1 + (2 + (3 + (4 + (50 + (10 + sum(10,20,1))))))              // 3
= 1 + (2 + (3 + (4 + (50 + (10 + (10 + sum(20,1)))))))          // 3
= 1 + (2 + (3 + (4 + (50 + (10 + (10 + (20 + sum(1))))))))      // 3
= 1 + (2 + (3 + (4 + (50 + (10 + (10 + (20 + (1 + sum())))))))) // 1
= 1 + (2 + (3 + (4 + (50 + (10 + (10 + (20 + (1 + 0))))))))  
= 1 + (2 + (3 + (4 + (50 + (10 + (10 + (20 + 1)))))))
= 1 + (2 + (3 + (4 + (50 + (10 + (10 + 21))))))
= 1 + (2 + (3 + (4 + (50 + (10 + 31)))))
= 1 + (2 + (3 + (4 + (50 + 41))))
= 1 + (2 + (3 + (4 + 91)))
= 1 + (2 + (3 + 95))
= 1 + (2 + 98)
= 1 + 100
= 101

答案 2 :(得分:1)

您也可以使用老式的循环方式...类似于Gabriel Tongs的答案。

function sum(...allArgs) {
  var total = 0;
  for(var i = 0; i < allArgs.length; i++){
    if(Array.isArray(allArgs[i])) {
      total += sum(...allArgs[i]) 
    } else {
      total += allArgs[i];
    }
  }
  return total;
}

答案 3 :(得分:1)

Array.flat和reduce是您真正需要的。

function sum(...allArgs) {
  return allArgs.flat().reduce((a, v) => a + v);
}

console.log("Result: " + sum([1,2,3,4],50,10,[10, 20],1));