如何从JSON中总结数字

How can I sum up number from JSON?

本文关键字:数字 JSON      更新时间:2023-09-26

我有以下JSON示例。我想把'Name'对应的'numberOfPoint'加起来,得到总点数。在这种情况下,名称A具有点数6的总数,名称B具有点数2的总数,并且名称C具有点数2。

{ "data": [
    {
        "id": {
            "year": 2015,
            "Name": "A"
        },
        "numberOfPoint": 2
    },
    {
        "id": {
            "year": 2014,
            "Name": "A"
        },
        "numberOfPoint": 2
    },
    {
        "id": {
            "year": 2014,
            "Name": "B"
        },
        "numberOfPoint": 2
    },
    {
        "id": {
            "year": 2014,
            "Name": "C"
        },
        "numberOfPoint": 2
    },
    {
        "id": {
            "year": 2013,
            "Name": "A"
        },
        "numberOfPoint": 2
    }]
}

如何对每个名称的numberOfPoint进行汇总?纯JavaScript或jQuery解决方案是可以的。

解决方案

假设obj是您的JSON,以下解决方案应该可以正常工作。

var result = {};
obj.data.forEach(function (a) { result[a["id"]["Name"]] = (result[a["id"]["Name"]] || 0) + a["numberOfPoint"]; });

result是存储值的位置。result看起来像:

{
    "A": 6,
    "B": 2,
    "C": 2
}

解释

一旦你能够"去肌肉",这就很简单了。首先定义对象(result)。然后我们循环遍历obj.data中的所有项目。接下来,我们找到与该项目相关联的name,并将其作为密钥。然后,我们使用OR简写来查看它是否被定义为not,如果没有,则将其设置为零。最后,添加值。这是重复的。

更新

对于这种东西,使用.reduce看起来更好:

obj.data.reduce(function (b,a) { return (b["id"]["Name"]] = (b[a["id"]["Name"]] || 0) + a["numberOfPoint"]) },{});

我喜欢用reduce做这种事情

yourObj.data.reduce(function(sums, elem) {
  var name = elem.id.Name;
  if (!sums[name]) sums[name] = 0;
  sums[name] += elem.numberOfPoint;
  return sums;
}, {});

输出

{A: 6, B: 2, C: 2}

一个更实用的方法可能看起来像这个

yourObj.data.map(function(elem) {
  return {key: elem.id.Name, value: elem.numberOfPoint};
}).reduce(function(sum, elem) {
  sum[elem.key] = (sum[elem.key] || 0) + elem.value;
  return sum;
}, {});

输出

{A: 6, B: 2, C: 2}

这种更分解的方法的优点是,您的函数体明显不那么复杂,只需快速浏览即可轻松理解,并且更易于重复使用


一旦我们分离出可重复使用的比特,这可能会是什么样子

// create some reusable functions
function mapToKeyValue(obj) {
  return {key: obj.id.Name, value: obj.numberOfPoint};
}
function sumKeyValues(sum, obj) {
  sum[obj.key] = (sum[obj.key] || 0) + obj.value;
  return sum;
}
// now manipulate your data with ease
var result = yourObj.items.map(mapToKeyValue).reduce(sumKeyValues, {});

输出

{A: 6, B: 2, C: 2}

您可以编写类似以下的函数

var sum = function(obj) {
    var result = {};
    for (var i = 0; i < obj.data.length; i++) {
        var element = obj.data[i];
        if (result[element.id.Name])
            result[element.id.Name] += element.numberOfPoint;
        else
            result[element.id.Name] = element.numberOfPoint;
    };
    return result;
};

并像下面的一样调用该函数

console.log(sum(givenData));

其中givenData是您提供的数据。

输出应该像下面的

{ A: 6, B: 2, C: 2 }

带着盐吃。。我很懒。

var x = {...},
    sum = {};
x.data.forEach(function (elem) {
    var _sum = sum[elem.id.Name];
    if (!_sum) {
        _sum = 0;
    }
    _sum += parseInt(elem.numberOfPoint, 10);
});