在JavaScript中对键值对数组的值求和

51

我已经定义了一个名为myData的JavaScript变量,它是这样一个new Array

var myData = new Array(['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0],
             ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], 
             ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], 
             ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]);

我想知道是否有可能对数组中的数字值求和(例如 0+0+21+2+0 等),并可能拥有一个变量存储结果,以便我可以在脚本标签之外使用,因为我有七个这样的数组对应一周中的每一天。之后我想基于此进行比较。如果可能的话,这是这种操作的最佳方法吗?


遍历数组并将内部数组的第二个元素相加。 - Felix Kling
11个回答

107
你可以使用Array.reduce方法:

const myData = [
  ['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0],
  ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], 
  ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], 
  ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]
];
const sum = myData
  .map( v => v[1] )                                
  .reduce( (sum, current) => sum + current, 0 );
  
console.log(sum);

请参见MDN


我猜应该是 prev[1]。无论如何,结果不会是 23 - VisioN
4
请注意,Array.reduce 是 ECMAscript 5 中的新增功能,因此可能不受所有浏览器支持 - 请参见此处 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce。该链接中还包括一些可供实现的代码,以克服此问题。 - Mark Walters
1
@VisioN:忘记了初始值,已经添加了。不应该是prev[1]。 @MarkWalters:是的,但可以使用来自MDN链接的shim(请参见答案)。 - KooiInc
1
使用ES6箭头函数:var sum = myData.reduce((sum, current) => (sum + current[1]), 0); - rjmunro

58

我认为最简单的方法可能是:

values.reduce(function(a, b){return a+b;})

7
很遗憾,这个回答不能适用于提问者的数据结构,但实际上这是处理数字数组的最佳方法。 - netpoetica
1
确保它们是数字不会有坏处:values.reduce(function(a, b){return +a + +b;}) - Fo.
1
@netpoetica myData.map(function(o) { return o[1]; }).reduce(a, b) { return a + b; }) @netpoetica myData.map(function(o) { return o[1]; }).reduce(a, b) { return a + b; }) - Paolo Moretti
1
使用EC6,这个代码可以写成values.reduce((a + b) => a + b) - hildende

18

请尝试以下操作

var myData = [['2013-01-22', 0], ['2013-01-29', 1], ['2013-02-05', 21]];

var myTotal = 0;  // Variable to hold your total

for(var i = 0, len = myData.length; i < len; i++) {
    myTotal += myData[i][1];  // Iterate over your first array and then grab the second element add the values up
}

document.write(myTotal); // 22 in this instance


我认为你的意思是 myData[i][1]。如果值本来就是数字,为什么要使用 parseFloat 呢? - Felix Kling
它输出了24156而不是应该的3。我已经使用“空值数组”进行了测试,但仍然得到相同的输出... - Daniela costina Vaduva
@FelixKling 它可以使用 myData[i][1],但我如何使得 myTotal 在其他脚本标签中可用? - Daniela costina Vaduva
丹尼尔,你修复了 Felix Kling 指出的错别字吗?记得在示例中写成 "myData[i][1]" 而不是错误的版本:"myData[1]"。 - Silas Hansen
@FelixKling 谢谢,我已经编辑过了。我猜我使用 parseFloat 时有些过于谨慎了。Daniela,我已经测试过了,它可以工作,请看这里 - http://jsbin.com/ibajas/1/ - Mark Walters
@DanielacostinaVaduva,为了使其对其他脚本标签可用:确保变量是全局的。这意味着它的声明(即“var mytotal”)应该出现在脚本标签之后,而不是在任何花括号“{}”内部。还要确保它在其他脚本标签之前加载,否则变量将无法初始化。 - Silas Hansen

13

我会使用reduce

var myData = new Array(['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0], ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]);

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

$("#result").text(sum);

可以在JSFiddle上找到。


12

创建一个求和方法会很好用,例如可以将sum函数添加到Array中

Array.prototype.sum = function(selector) {
    if (typeof selector !== 'function') {
        selector = function(item) {
            return item;
        }
    }
    var sum = 0;
    for (var i = 0; i < this.length; i++) {
        sum += parseFloat(selector(this[i]));
    }
    return sum;
};

那么你可以这样做

> [1,2,3].sum()
6

而在你的情况下

> myData.sum(function(item) { return item[1]; });
23

编辑:扩展内置函数可能会受到不良反应,因为如果每个人都这样做,我们将会得到意外覆盖彼此的事情(命名空间冲突)。如果您愿意,可以将sum函数添加到某个模块中并将数组作为参数接受。

那可能意味着将签名更改为myModule.sum = function(arr, selector) {,然后this将变为arr


8

或者在ES6中:

values.reduce((a, b) => a + b),

例子:

[1,2,3].reduce((a, b)=>a+b) // return 6

2

如果您想在求和的同时丢弃数组,可以这样做(例如,stack 是该数组):

var stack = [1,2,3],
    sum = 0;
while(stack.length > 0) { sum += stack.pop() };

1
你可以使用原生的数组 map 方法。map 方法 (数组) (JavaScript)
var myData = new Array(['2013-01-22', 0], ['2013-01-29', 0], ['2013-02-05', 0],
             ['2013-02-12', 0], ['2013-02-19', 0], ['2013-02-26', 0], 
             ['2013-03-05', 0], ['2013-03-12', 0], ['2013-03-19', 0], 
             ['2013-03-26', 0], ['2013-04-02', 21], ['2013-04-09', 2]);
var a = 0;
myData.map( function(aa){ a += aa[1];  return a; });
是你的结果

1

其中0是初始值

Array.reduce((currentValue, value) => currentValue +value,0)

或者

Array.reduce((currentValue, value) =>{ return currentValue +value},0)

或者

[1,3,4].reduce(function(currentValue, value) { return currentValue + value},0)

0
JavaScript内置的数组reduce不是标准,但您可以使用underscore.js:
var data = _.range(10);
var sum = _(data).reduce(function(memo, i) {return memo + i});

会变成

var sumMyData = _(myData).reduce(function(memo, i) {return memo + i[1]}, 0);

针对您的情况,请查看这个fiddle


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接