Summarize and Group JSON object in Jquery

倖福魔咒の 提交于 2019-12-10 23:25:51

问题


I am having problems summarizing and grouping my object in Jquery as I would like to group by country and then have a grand total based on subperiods 4,5,and 6 for values within col1. The col1, col2, col3 are dynamic, but using this is an example.

What I need is to get the total by country which is stored in the country variable, grand total per subperiod stored in the columns variable, and the total count stored in the averages variable.

Here is my code in jsfiddle:

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

My object:

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"
}];

Here is the end result which I would like to get and this is based on summarizing col1 per subperiod per country.

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

Grand total for the subperiods 4,5,6 should show as:

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

I would also like to get the total count per country, per subperiod:

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

I would like to try to stick to my code as close as possible. Thanks, appreciate the help.


回答1:


This should do the trick:

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':{}}}`

Returns:

{
    "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
        }
    }
}

Please note this doesn't change g_jsonData, it only returns the new object.
To use the new object, you have to assign it to a variable, of course:

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

You could make the code a little shorter (/easier to look at) like this:

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':{}});

Now it's relatively easy to make col1 a variable name.
Replace:

v = +curr.col1;

With:

v = +curr['col1'];

Or:

v = +curr[someVariable];


来源:https://stackoverflow.com/questions/21874436/summarize-and-group-json-object-in-jquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!