0

OK guys need some help out there. I'm still learning Javascript and its interactions JSON. I have a a JSON like this

[{
  "categories":"Food",
  "subcategories":"Shares",
  "pid":"111",
  "title":"Smoked Salmon Dip",
  "description":"Rich and savory salmon dip, whipped with fresh dill accompanied with     croustades"
   },
   {
  "categories":"Food",
  "subcategories":"Shares",
  "pid":"112",
  "title":"Sweet Goat Cheese Flatbread",
  "description":"Delicate grilled Naan flatbread coated with delish tomato jam and topped with melted goat cheese, roasted garlic, fennel, onion, pear, shiitake mushroom and arugula."
 },
 {
  "categories":"Food",
  "subcategories":"Snacks",
  "pid":"100",
  "title":"Beer Chili",
  "description":"Hot & satisfying short rib chili with black beans, smoked jalapenos, and fresh corn. Topped with aged cheddar cheese and sour cream."
 }];

But what I need is an JSON that looks like this

{
 "menu":{
  "categories":[
     {
                "name":"Food",
                "subcategories":[
                    {
                    "name":"Shares",
                    "items":[
                        {
                        "pid":"111",
                        "title":"Smoked Salmon Dip",
                        "description":"Rich and savory salmon dip, whipped with fresh dill accompanied with croustades"
                        },
                        {
                        "pid":"112",
                        "title":"Sweet Goat Cheese Flatbread",
                        "description":"Delicate grilled Naan flatbread coated with delish tomato jam and topped with melted goat cheese, roasted garlic, fennel, onion, pear, shiitake mushroom and arugula."
                        }
                        ]
                    },
                    {
                    "name":"Snacks",
                    "items":[
                        {                       
                        "pid":"100",
                        "title":"Beer Chili",
                        "description":"Hot & satisfying short rib chili with black beans, smoked jalapenos, and fresh corn. Topped with aged cheddar cheese and sour cream."
                        }
                        ]
                    }
                    ]
        }]
        }
     }

I know its a bit ugly and but I'm having trouble figuring out how to build the new JSON as i iterate through my current one.

Any help getting me going would be awesome

ddpishere
  • 751
  • 1
  • 8
  • 23

2 Answers2

0

I workout a solution, but I'm not sure how it will handle big json data. Assume that the json var stores your data:

categories = [];
json.forEach(function(entry) {  
    var cindex = categories.map(function(category) { 
        return category.name; 
    }).indexOf(entry.categories);

    if (cindex < 0) {
        // Not found in categories array
        cindex = categories.push({
            name: entry.categories,
            subcategories: []
        }) - 1; // -1 to fix the index
    }

    // Lets search the subcategory
    var category = categories[cindex];

    var sindex = category.subcategories.map(
        function(subcategory) {
            return subcategory.name;
        }
    ).indexOf(entry.subcategories);

    if (sindex < 0) {
      // Not Found
        sindex = category.subcategories.push({
            name: entry.subcategories,
            items: []
        }) - 1; 
    } 
    // Subcategory exists. Just push
    category.subcategories[sindex].items.push({
        pid: entry.pid,        
        description: entry.description,
        title: entry.title
    });
});

var menu = {
    menu: {
        categories: categories
    }
};

Working Fiddle

Beterraba
  • 6,515
  • 1
  • 26
  • 33
  • Thanks @Beterraba That looks like exactly what I need. I will work with it as I learn from example. Thanks again – ddpishere Jan 10 '14 at 14:24
  • I noticed this doesn't work unless jQuery is available. Can you point out the jquery specific items? – ddpishere Jan 11 '14 at 18:34
  • @ddpishere is the `json.forEach`. It isnt jQuery, but some browsers (IE8 later) still doesnt implement. You can see [this answer](http://stackoverflow.com/questions/9329446/for-each-in-an-array-how-to-do-that-in-javascript) for more details. Just change the `json.forEach` to a regular `for(..;..;..)` and you will be good. – Beterraba Jan 11 '14 at 19:20
  • I was thinking that was it. Thanks! – ddpishere Jan 11 '14 at 20:04
0

I gave this a shot and might as well post my results. The data doesn't line up perfectly with what you have. It doesn't require jQuery, and it can be used to sort data multiple times.

Object.prototype.groupBy = function(itemName, preGrouped)
{
    if(preGrouped)
    {
        for(prop in this)
        {
            if(typeof(this[prop]) === 'object' && this[prop].groupBy !== undefined)
            {
                var reGroup = this[prop].groupBy(itemName);  
                this[prop] = reGroup;
            }
        }
        return this;
    }
    else
    {
        var uniqueItems = {};
        var uniqueItemLength = 0;
        for(var i=0, length=this.length; i < length; i++)
        {
           var item = this[i]; 
           var z =0;
           var found = false;
           while(z < uniqueItemLength)
           {     
               if(item[itemName] in uniqueItems)
               {
                   uniqueItems[item[itemName]].push(item);
                   found = true;
                   break;
               }
               z++;
           }
            if(!found)
            {
                uniqueItems[item[itemName]] = [];
                uniqueItems[item[itemName]].push(item); 
                uniqueItemLength++;
            }      
        }
        return uniqueItems;
    } 
}

It gets called by:

var convertedData = oldJSON.groupBy('categories').groupBy('subcategories', true)

Beterraba's answer is correct. I put some time in this one and figured I'd at least post. Maybe it would help someone else.

http://jsfiddle.net/8VRuy/

cgatian
  • 22,047
  • 9
  • 56
  • 76
  • Thanks @cgatian as I said before I learn best from example and seeing 2 different approaches helps me learn even more. – ddpishere Jan 10 '14 at 14:25