【问题标题】:Summarize and Group JSON object in Jquery在 Jquery 中汇总和分组 JSON 对象
【发布时间】:2014-02-19 08:03:49
【问题描述】:

我在 Jquery 中总结和分组我的对象时遇到问题,因为我想按国家/地区分组,然后根据子期间 4、5 和 6 对 col1 内的值进行总计。 col1、col2、col3 是动态的,但使用这个只是一个例子。

我需要的是按国家/地区获取总数,该总数存储在国家变量中,每个子期间的总计存储在列变量中,总计数存储在平均值变量中。

这是我在 jsfiddle 中的代码:

http://jsfiddle.net/8vVK7/8/

我的对象:

var g_jsonData =

[
{
    "Country": "Spain",
    "Year": "2000",
    "Subperiod": "4",
    "col1": "75",
    "col2": "500",
    "col3": "200"
},
{
    "Country": "Spain",
    "Year": "2001",
    "Subperiod": "4",
    "col1": "50",
    "col2": "500",
    "col3": "300"
},
{
    "Country": "Spain",
    "Year": "2002",
    "Subperiod": "4",      
    "col1": "50",
    "col2": "200",
    "col3": "300"
},
{
    "Country": "Spain",
    "Year": "2003",
    "Subperiod": "4",      
    "col1": "",
    "col2": "200",
    "col3": "300"
},
{
    "Country": "Spain",
    "Year": "2005",
    "Subperiod": "5",
    "col1": "125",
    "col2": "500",
    "col3": "300"
},
{
    "Country": "Spain",
    "Year": "2012",
    "Subperiod": "6",
    "col1": "100.75",
    "col2": "500",
    "col3": "200"
},
{
    "Country": "Spain",
    "Year": "2013",
    "Subperiod": "6",
    "col1": "200",
    "col2": "500",
    "col3": "300"
},
{
    "Country": "France",
    "Year": "2000",
    "Subperiod": "4",    
    "col1": "100",
    "col2": "100",
    "col3": "300"
},
{
    "Country": "France",
    "Year": "2001",
    "Subperiod": "4",      
    "col1": "100",
    "col2": "100",
    "col3": "300"
},
{
    "Country": "France",
    "Year": "2002",
    "Subperiod": "4",      
    "col1": "100",
    "col2": "200",
    "col3": "300"
},
{
    "Country": "France",
    "Year": "2005",
    "Subperiod": "5",      
    "col1": "100",
    "col2": "200",
    "col3": "300"
},
{
    "Country": "France",
    "Year": "2012",
    "Subperiod": "6",      
    "col1": "100",
    "col2": "100",
    "col3": "300"
},
{
    "Country": "France",
    "Year": "2013",
    "Subperiod": "6",      
    "col1": "100",
    "col2": "100",
    "col3": "300"
}];

这是我想要得到的最终结果,这是基于对每个国家/地区每个子周期的 col1 进行汇总。

countries =    
{
   "Spain":{
      "4":175,
      "5":125,
      "6":300.75
  },    
   "France":{
      "4":300,
      "5":100,
      "6":200,
  }
}

子期间 4、5、6 的总计应显示为:

columns = 
{
    "4":475,
    "5":225,
    "6":500.75
} 

我还想获得每个国家、每个子时段的总数:

averages = 
{
   "Spain":{
      "4":3,
      "5":1,
      "6":2
  },    
   "France":{
      "4":3,
      "5":1,
      "6":2
  }
}   

我想尽量坚持我的代码。 谢谢,感谢您的帮助。

【问题讨论】:

  • averages 中的值应该如何计算?
  • @Cerbrus 我将使用西班牙作为 col1 子周期 4 的示例,它有 75 + 50 + 50 + ""。所以总计数为 4。但是,因为在 Subperiod 4 Year 2003 中有一个空白值,我们不计算它。所以总数是 3。这有意义吗?
  • @Cerbrus 可能平均值不是一个好的变量名称,因为它可能应该称为 Count。
  • 啊,是的,count 会更有意义:P

标签: javascript jquery json grouping summary


【解决方案1】:

这应该可以解决问题:

g_jsonData.reduce(function(out, curr){
    // Make sure the current country exists on the output object.
    // Then add the current object's col1 to the current country's subperiod,
    //   checking to see if the current subperiod exists. Also, cast the `col1` to int `(+curr.col1)`
    out.countries[curr.Country] = out.countries[curr.Country] || {};
    out.countries[curr.Country][curr.Subperiod] = (out.countries[curr.Country][curr.Subperiod] || 0) + (+curr.col1);

    // And add it to the total, too.
    out.columns[curr.Subperiod] = (out.columns[curr.Subperiod] || 0) + (+curr.col1);

    // Count occurences
    out.count[curr.Country] = out.count[curr.Country] || {};
    out.count[curr.Country][curr.Subperiod] = (out.count[curr.Country][curr.Subperiod] || 0) + 1;
    return out;
},
{'columns':{},'countries':{},'count':{}}); // second parameter to `reduce` is a default object, in this case: `{'columns':{},'countries':{},'count':{}}}`

返回:

{
    "columns": {
        "4": 475,
        "5": 225,
        "6": 500.75
    },
    "countries": {
        "Spain": {
            "4": 175,
            "5": 125,
            "6": 300.75
        },
        "France": {
            "4": 300,
            "5": 100,
            "6": 200
        }
    },
    "count": {
        "Spain": {
            "4": 3,
            "5": 1,
            "6": 2
        },
        "France": {
            "4": 3,
            "5": 1,
            "6": 2
        }
    }
}

请注意,这不会改变 g_jsonData,它只会返回新对象。
当然,要使用新对象,您必须将其分配给变量:

var output = g_jsonData.reduce(func....);

您可以像这样使代码更短(/更易于查看):

g_jsonData.reduce(function(out, curr){
    var c = curr.Country,
        s = curr.Subperiod,
        v = +curr.col1; //value cast to int already
    out.countries[c]    =  out.countries[c]    || {};
    out.countries[c][s] = (out.countries[c][s] || 0 ) + v;
    out.count[c]        =  out.count[c]        || {};
    out.count[c][s]     = (out.count[c][s]     || 0 ) + 1;
    out.columns[s]      = (out.columns[s]      || 0 ) + v;
    return out;
},
{'columns':{},'countries':{},'count':{}});

现在将col1 设为变量名相对容易。
替换:

v = +curr.col1;

与:

v = +curr['col1'];

或者:

v = +curr[someVariable];

【讨论】:

  • 已编辑以稍微更改数据格式。我不太确定您是如何获得“平均值”中的数字的。
  • 我将使用西班牙作为 col1 子周期 4 的示例,它有 75 + 50 + 50 + ""。所以总计数为 4。但是,因为在 Subperiod 4 Year 2003 中有一个空白值,我们不计算它。所以总数是 3。这有意义吗?
  • @MoxieC:添加计数。
  • 假设我不知道 col1 的名称,因为名称可能是动态的,您将如何编码。另外,假设我想按年份而不是国家来分组,有没有更通用的方法?
  • @MoxieC:看看我回答的最后一部分。
猜你喜欢
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 1970-01-01
  • 2020-03-12
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多