关于javascript:如何查找数字数组的和

How to find the sum of an array of numbers

给定一个数组[1, 2, 3, 4],如何找到它的元素之和?(在这种情况下,金额为10。)

我认为$.each可能有用,但我不确定如何实现它。


在Lisp中,这正是reduce的工作。你会看到这种代码:

1
(reduce #'+ '(1 2 3)) ; 6

幸运的是,在javascript中,我们也有reduce!不幸的是,+是一个运算符,而不是函数。但我们可以让它漂亮!这里,看一下:

1
2
3
4
5
6
7
const sum = [1, 2, 3].reduce(add);

function add(accumulator, a) {
    return accumulator + a;
}

console.log(sum); // 6

那不是很漂亮吗?-)

甚至更好!如果您使用的是ecmascript 2015(又名ecmascript 6),那么它可能非常漂亮:

1
2
const sum = [1, 2, 3].reduce((partial_sum, a) => partial_sum + a);
console.log(sum); // 6


为什么不减少?这通常有点违反直觉,但使用它来求和非常简单:

1
2
var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);


建议(使用默认值减少)

array.prototype.reduce可用于遍历数组,将当前元素值添加到前一个元素值的总和中。

1
2
3
4
5
6
console.log(
  [1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
  [].reduce((a, b) => a + b, 0)
)

无默认值

你得到一个类型错误

1
2
3
console.log(
  [].reduce((a, b) => a + b)
)

ES6箭头功能之前

1
2
3
4
5
6
7
console.log(
  [1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)

console.log(
  [].reduce(function(acc, val) { return acc + val; }, 0)
)

非数字输入

如果非数字是可能的输入,您可能想处理它?

1
2
3
4
5
6
7
8
9
10
console.log(
  ["hi", 1, 2,"frog"].reduce((a, b) => a + b)
)

let numOr0 = n => isNaN(n) ? 0 : n

console.log(
  ["hi", 1, 2,"frog"].reduce((a, b) =>
    numOr0(a) + numOr0(b))
)

不建议使用危险评估

我们可以使用eval来执行javascript代码的字符串表示。使用array.prototype.join函数将数组转换为字符串,我们将[1,2,3]更改为"1+2+3",计算结果为6。

1
2
3
4
5
6
7
8
console.log(
  eval([1,2,3].join('+'))
)

//This way is dangerous if the array is built
// from user input as it may be exploited eg:

eval([1,"2;alert('Malicious code!')"].join('+'))

当然,显示警报并不是最糟糕的事情。我之所以把这个问题包括在内,是因为我不认为它被澄清了,所以我把它作为一个答案。


1
2
3
var arr = [1,2,3,4];
var total=0;
for(var i in arr) { total += arr[i]; }


1
2
3
4
var total = 0;
$.each(arr,function() {
    total += this;
});


这可以通过循环遍历所有项,并在每次迭代中将它们添加到一个sum变量中来实现。

1
2
3
var array = [1, 2, 3];

for (var i = 0, sum = 0; i < array.length; sum += array[i++]);

javascript不知道块作用域,因此可以访问sum

1
console.log(sum); // => 6

如上所述,但作为简单函数进行注释和准备:

1
2
3
4
5
6
7
8
9
10
11
function sumArray(array) {
  for (
    var
      index = 0,              // The iterator
      length = array.length,  // Cache the array length
      sum = 0;                // The total amount
      index < length;         // The"for"-loop condition
      sum += array[index++]   // Add number on each iteration
  );
  return sum;
}


如果您碰巧使用lodash,可以使用sum函数

1
2
array = [1, 2, 3, 4];
sum = _.sum(array); // sum == 10


1
2
3
arr.reduce(function (a, b) {
    return a + b;
});

参考:array.prototype.reduce()


1
2
3
4
// Given array 'arr'
var i = arr.length;
var sum = 0;
while (--i) sum += arr[i];

这将平均需要1.57 ms/次(在100个随机正态数的数组中测量1000次以上),相比之下,使用上述eval()方法时为3.604 ms/次,使用(i,length,++)循环的标准时为2.151 ms/次。

方法说明:此测试是在Google应用程序脚本服务器上运行的,因此它们的javascript引擎与chrome几乎相同。

编辑:--i而不是i--每次运行可节省0.12毫秒(i—1.7)

编辑:神圣的咒骂,别在意这整篇文章。使用上面提到的reduce()方法,它只运行1毫秒。


你也可以用还原剂。

1
[1,2,3,4,5,6].reduceRight(function(a,b){return a+b;})

结果输出为21。

参考:https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_objects/array/reducceright


滑稽手法:

1
eval([1,2,3].join("+"))


好的,假设您有下面这个数组:

1
const arr = [1, 2, 3, 4];

让我们开始研究许多不同的方法,因为我在这里找不到任何全面的答案:

1)使用内置reduce()。

1
2
3
4
function total(arr) {
  if(!Array.isArray(arr)) return;
  return arr.reduce((a, v)=>a + v);
}

2)用于回路

1
2
3
4
5
6
7
8
function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0;
  for (let i=0,l=arr.length; i<l; i++) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

3)使用while循环

1
2
3
4
5
6
7
8
function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0, i=-1;
  while (++i < arr.length) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

4)使用数组foreach

1
2
3
4
5
6
7
8
function total(arr) {
  if(!Array.isArray(arr)) return;
  let sum=0;
  arr.forEach(each => {
    sum+=each;
  });
  return sum;
};

这样称呼它:

1
total(arr); //return 10

不建议将类似这样的原型用于数组…


有没有人想找一个像我这样的功能性单管飞机?拿这个:

1
sum= arr.reduce(function (a, b) {return a + b;}, 0);


标准的javascript解决方案:

1
2
3
4
5
6
7
8
9
10
11
var addition = [];
addition.push(2);
addition.push(3);

var total = 0;
for (var i = 0; i < addition.length; i++)
{
    total += addition[i];
}
alert(total);          // Just to output an example
/* console.log(total); // Just to output an example with Firebug */

这对我有效(结果应该是5)。我希望这种解决方案没有隐藏的缺点。


我对javascript和编码是个初学者,但我发现一个简单而简单的数组中的数字求和方法如下:

1
2
3
4
5
    var myNumbers = [1,2,3,4,5]
    var total = 0;
    for(i=0; i<myArray.length; i++){
        total += myArray[i];
    }

基本上,我想贡献这个,因为我没有看到很多不使用内置函数的解决方案,而且这个方法很容易编写和理解。


1
var totally = eval(arr.join('+'))

这样就可以在数组中放置各种奇异的东西。

1
var arr = ['(1/3)','Date.now()','foo','bar()',1,2,3,4]

我只是半开玩笑。


一小段javascript代码可以完成这项工作:

1
2
3
4
5
6
7
8
9
var numbers = [1,2,3,4];
var totalAmount = 0;

for (var x = 0; x < numbers.length; x++) {

    totalAmount += numbers[x];
}

console.log(totalAmount); //10 (1+2+3+4)

一些人建议在Array.prototype中添加一个.sum()方法。这通常被认为是不好的做法,所以我不建议你这么做。

如果你仍然坚持这样做,那么这是一种简洁的写作方式:

1
Array.prototype.sum = function() {return [].reduce.call(this, (a,i) => a+i, 0);}

那么:[1,2].sum(); // 3

注意,添加到原型的函数使用的是ES5和ES6函数以及箭头语法的混合。声明function允许该方法从您正在操作的Array中获取this上下文。我使用=>来简化reduce调用中的内容。


这里有一个优雅的一行解决方案,它使用了堆栈算法,不过要理解这个实现的美可能需要一些时间。

1
2
3
const getSum = arr => (arr.length === 1) ? arr[0] : arr.pop() + getSum(arr);

getSum([1, 2, 3, 4, 5]) //15

基本上,函数接受一个数组并检查数组是否只包含一个项。如果为false,则从堆栈中弹出最后一个项并返回更新的数组。

这段代码的好处在于,该函数包括arr[0]检查,以防止无限循环。一旦到达最后一项,它将返回整个和。


使用reduce

1
2
3
4
5
let arr = [1, 2, 3, 4];

let sum = arr.reduce((v, i) => (v + i));

console.log(sum);


可以将reduce()方法与lambda表达式结合使用:

1
[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);

不需要initial value!因为如果没有传递initial value,则不会在列表的第一个元素上调用callback function,而是将第一个元素作为initial value传递。非常酷的功能:)

1
2
3
4
[1, 2, 3, 4].reduce((a, x) => a + x) // 10
[1, 2, 3, 4].reduce((a, x) => a * x) // 24
[1, 2, 3, 4].reduce((a, x) => Math.max(a, x)) // 4
[1, 2, 3, 4].reduce((a, x) => Math.min(a, x)) // 1

这里的技巧很酷,我对很多安全的传统答案都很挑剔,没有缓存数组的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function arraySum(array){
  var total = 0,
      len = array.length;

  for (var i = 0; i < len; i++){
    total += array[i];
  }

  return total;
};

var my_array = [1,2,3,4];

// Returns 10
console.log( arraySum( my_array ) );

在不缓存数组长度的情况下,JS编译器需要在每次循环迭代时遍历数组来计算长度,在大多数情况下这是不必要的开销。V8和许多现代浏览器都为我们优化了这一点,因此它比以前更不受关注,但也有一些较旧的设备可以从这个简单的缓存中获益。

如果长度会发生变化,那么如果您不知道为什么要缓存长度,那么缓存可能会导致一些意外的副作用,但是对于一个可重用的函数来说,它的唯一目的是获取一个数组并将值加在一起,这非常适合。

这是这个arraysum函数的代码笔链接。http://codepen.io/brandonbrule/pen/zgejyv

这可能是一种过时的思维定势,一直困扰着我,但我不认为在这种情况下使用它有什么缺点。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Object.defineProperty(Object.prototype, 'sum', {
    enumerable:false,
    value:function() {
        var t=0;for(var i in this)
            if (!isNaN(this[i]))
                t+=this[i];
        return t;
    }
});

[20,25,27.1].sum()                 // 72.1
[10,"forty-two",23].sum()          // 33
[Math.PI,0,-1,1].sum()             // 3.141592653589793
[Math.PI,Math.E,-1000000000].sum() // -999999994.1401255

o = {a:1,b:31,c:"roffelz",someOtherProperty:21.52}
console.log(o.sum());              // 53.519999999999996


这个容易多了

1
2
3
4
5
6
7
8
9
10
11
function sumArray(arr) {
    var total = 0;
    arr.forEach(function(element){
        total += element;
    })
    return total;
}

var sum = sumArray([1,2,3,4])

console.log(sum)

我看到了所有关于"减少"解决方案的答案

1
2
3
4
5
6
var array = [1,2,3,4]
var total = 0
for (var i = 0; i < array.length; i++) {
    total += array[i]
}
console.log(total)

这些都是很好的答案,但是如果数字是按顺序排列的,就像问题(1,2,3,4)中的那样,你可以通过应用公式很容易地做到这一点。(n*(n+1))/2,其中n是最后一个数字


试试这个…

1
2
3
4
5
6
7
function arrSum(arr){
    total = 0;  
    arr.forEach(function(key){
        total = total + key;            
    });
    return total;
}


您只需要普通的javascript:

1
2
3
4
5
6
7
8
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; a.forEach(function(e){sum += e}); sum
10
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; a.forEach(e => sum += e); sum
10
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; for(e in a) sum += e; sum
"00123foobar"
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; for(e of a) sum += e; sum
10

这个函数可以把所有的数字相加-

1
2
3
4
5
6
7
8
 function array(arr){
   var sum = 0;
   for (var i = 0; i< arr.length; i++){
    sum += arr[i];
   }
   console.log(sum);
 }
 array([5, 1, 3, 3])

一个简单的方法示例:

1
2
3
4
5
6
7
8
9
10
11
function add(array){
    var arraylength = array.length;
    var sum = 0;
    for(var timesToMultiply = 0; timesToMultiply<arraylength; timesToMultiply++){
        sum += array[timesToMultiply];
    }

    return sum;
}

console.log(add([1, 2, 3, 4]));

带ES6静止参数

1
2
3
4
5
6
7
8
9
10
11
let array = [1, 2, 3, 4]

function sum(...numbers) {
    let total = 0;
    for (const number of numbers) {
        total += number;
    }
    return total;
}

console.log(sum(...array));


只需使用此功能:

1
2
3
4
5
6
7
8
function sum(pArray)
{
  pArray = pArray.reduce(function (a, b) {
      return a + b;
  }, 0);

  return pArray;
}

1
2
3
4
5
6
7
8
9
10
11
12
function sum(pArray)
{
  pArray = pArray.reduce(function (a, b) {
      return a + b;
  }, 0);

  return pArray;
}

var arr = [1, 4, 5];

console.log(sum(arr));


一个"复制"的问题问如何对二维数组执行此操作,因此这是对回答该问题的简单调整。(差异仅为6个字符[2], 0,它在每个子数组中查找第三个项目并传递初始值零):

1
2
3
4
5
6
7
const twoDimensionalArray = [
  [10, 10, 1],
  [10, 10, 2],
  [10, 10, 3],
];
const sum = twoDimensionalArray.reduce( (partial_sum, a) => partial_sum + a[2], 0 ) ;
console.log(sum); // 6


对于非常大的数量,循环或减少可能是过程密集型的。用高斯怎么样?

1
sum = (n * (n+1))/2;

来自MathCentral。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    <!DOCTYPE html>
    <html>
    <body>

      <p>
Click the button to join two arrays.
</p>
      <button onclick="myFunction()">Try it</button>
      <p id="demo">
</p>
   
var hege = [1, 2,4,6,7,8,8];
var stale = [1, 2,4,5];
function myFunction() {
    console.log((hege.length > stale.length))    
    var children  = (hege.length > stale.length)? abc1() :abc2();       document.getElementById("demo").innerHTML = children;
}
function abc1(){
    console.log(hege,"Abc1")    
    var abcd=hege.map(function (num, idx) {
        console.log(hege.length , idx)
        return stale.length>idx?num + stale[idx]:num;
    })
    return abcd;
}

function abc2(){

    console.log(hege,"Abc2",stale)    
    var abcd=stale.map(function (num, idx) {
        console.log(hege.length , idx)
        return hege.length>idx?num + hege[idx]:num;
    })
    return abcd;
}


</body>
</html>

使用递归

1
2
var sum = (arr) => arr.length === 1 ? arr[0] : arr.shift() + sum(arr);
sum([1,2,3,4]) // 10


使用map

1
2
3
4
5
6
var sum = 0;
arr.map(function(item){
    sum += item;
});

// sum now contains the total.

您可以潜在地将该方法添加到数组原型中。

1
2
3
4
5
6
7
Array.prototype.sum = function(){
    var sum = 0;
    this.map(function(item){
        sum += item;
    });
    return sum;
}

然后您可以在类似这样的任何数组上使用它:

1
arr.sum();