19

Sorry if this has been asked before, but I couldn't find a good example of what I'm trying to accomplish. Maybe I'm just not searching for the right thing. Please correct me if there's an explanation of this somewhere. Anyway...

I have JSON data structured like so...

{"Result":[
    {"Level":"ML","TeamName":"Team 1","League":"League 1"},
    {"Level":"ML","TeamName":"Team 2","League":"League 2"},
    {"Level":"ML","TeamName":"Team 3","League":"League 3"},
    {"Level":"3A","TeamName":"Team 4","League":"League 1"},
    {"Level":"3A","TeamName":"Team 5","League":"League 2"},
    {"Level":"3A","TeamName":"Team 6","League":"League 3"},
    {"Level":"2A","TeamName":"Team 7","League":"League 1"},
    {"Level":"2A","TeamName":"Team 8","League":"League 2"},
    {"Level":"2A","TeamName":"Team 9","League":"League 3"},
]}

I would like to group, or restructure it like so...

{"Result":[
    {"ML":[
        {"TeamName":"Team 1","League":"League 1"},
        {"TeamName":"Team 2","League":"League 2"},
        {"TeamName":"Team 3","League":"League 3"}
    ]},
    {"3A":[
        {"TeamName":"Team 4","League":"League 1"},
        {"TeamName":"Team 5","League":"League 2"},
        {"TeamName":"Team 6","League":"League 3"}
    ]},
    {"2A":[
        {"TeamName":"Team 7","League":"League 1"},
        {"TeamName":"Team 8","League":"League 2"},
        {"TeamName":"Team 9","League":"League 3"}
    ]}
]}

How would I accomplish this with Javascript/jQuery? Unfortunately I can't edit what the server is sending me.

ekad
  • 14,436
  • 26
  • 44
  • 46
ksumarine
  • 782
  • 2
  • 12
  • 33
  • 8
    [What have you tried?](http://whathaveyoutried.com/) This is a trivial problem... – Niet the Dark Absol Jun 28 '12 at 15:36
  • Convert the JSON to an object, copy relevant parts to another object, and convert 2nd object to json. You can do it. – Jonathan M Jun 28 '12 at 15:38
  • @JonathanM That last step may not even be necessary, since assumedly they're going to want to actually do something with the object at some point. – Anthony Grist Jun 28 '12 at 15:39
  • Honestly, I haven't tried much. I'm trying to wrap my head around how to go about this. I don't know if I have to use a combination of loops and $.grep() for this or not. Any guidance or help would be great. – ksumarine Jun 28 '12 at 15:40

1 Answers1

28

Just keep track of it all in an object:

let groups = Object.create(null);

data.forEach(item => {
    if (!groups[item.Level]) {
        groups[item.Level] = [];
    }

    groups[item.Level].push({
        TeamName: item.TeamName,
        League: item.League
    });
});

let result =
    Object.entries(groups)
        .map(([k, v]) => ({[k]: v}));
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Can your for loop (and next line) be simplified into `for( item in data )` ? – Timothy Aaron Jun 28 '12 at 15:47
  • 2
    @TimothyAaron: No, JavaScript's `for in` loop iterates over keys, not values, and you shouldn't use it to iterate over arrays. So, we're still waiting for widespread adoption of `for each` :D – Ry- Jun 28 '12 at 15:52
  • He says he's using jQuery, so you could use $.each. – Julian Jun 28 '12 at 15:55
  • @Julian: Right, thanks; I'll add that. – Ry- Jun 28 '12 at 15:57
  • That's great...thank you very much for some ideas. – ksumarine Jun 28 '12 at 16:01
  • I understood the first part of the jQuery code you gave, but then you lost me at `var result = $.map` is this just another way of doing it? If so, still dont follow that, but I presume I can just use the first part from `var groups`. It just seems like that second part has nothing to do with the first and is not needed. So im hoping its just an alternative – redfox05 Aug 24 '15 at 13:54
  • @Russell: The final result is an array (according to the question), and that’s the only way to get that array, but I accidentally passed `data` to `map` instead of `groups`. – Ry- Aug 24 '15 at 18:22
  • Another way of iterating over objects I use a lot is this: `Object.keys(groups).forEach(function(key, index) { //*code here* });`. I find it much cleaner than using call. – inolasco Apr 08 '16 at 18:32