1

I have a json file that's returned from a service am using. I have no control over the service therefore can't change the structure of the json file. The file looks something like:

menu":[    
 {
  "section":"theMobileMenu",
  "key":"menuItem1Title",
  "content":"Mobile context and principles"
},
{
  "section":"theMobileMenu",
  "key":"menuItem1Link",
  "content":"/mobile/index.html"
},
{
  "section":"theMobileMenu",
  "key":"menuItem2Title",
  "content":"Global guidelines"
},
{
  "section":"theMobileMenu",
  "key":"menuItem2Link",
  "content":"/mobile/global-guidelines.html"
},
{
  "section":"theMobileMenu",
  "key":"menuItem3Title",
  "content":"First impressions"
},
{
  "section":"theMobileMenu",
  "key":"menuItem3Link",
  "content":"/mobile/first-impressions.html"
}
]

I want to create an array of objects like the one below

    "menu":[
 {
 "title":"Mobile context and principles",
 "link":"/mobile/index.html"
 },
{
"title":"Global guidelines",
 "link":"/mobile/global-guidelines.html"
},
{
"title":"First impressions",
 "link":"/mobile/first-impressions.html"
}
]

I've tried something like:

var newData = []
var curData = {};
var x = 1;

$.each(data.menu, function(i, val) {            
    if(val.key == 'menuItem'+x+'Link'){
        curData.link = val.content;         
    }
    if(val.key == 'menuItem'+x+'Title'){
        curData.title = val.content;            
    }
    newData.push(curData)
    curData = []
    x++;            
})  

This doesn't work very well. Any ideas on how to work this out?

5
  • Please check data should be data.menu. Commented Dec 19, 2015 at 7:51
  • I've edited to data.menu. Doesn't make a difference though Commented Dec 19, 2015 at 8:04
  • Is it goes to loop? can you check this? Commented Dec 19, 2015 at 8:08
  • @mr_j..is it below cod working? Commented Dec 19, 2015 at 8:14
  • your answer returns a blank array. Will's answer works Commented Dec 19, 2015 at 8:25

4 Answers 4

1

Try this:

var data = [{
    "section": "theMobileMenu",
    "key": "menuItem1Title",
    "content": "Mobile context and principles"
}, {
    "section": "theMobileMenu",
    "key": "menuItem1Link",
    "content": "/mobile/index.html"
}, {
    "section": "theMobileMenu",
    "key": "menuItem2Title",
    "content": "Global guidelines"
}, {
    "section": "theMobileMenu",
    "key": "menuItem2Link",
    "content": "/mobile/global-guidelines.html"
}, {
    "section": "theMobileMenu",
    "key": "menuItem3Title",
    "content": "First impressions"
}, {
    "section": "theMobileMenu",
    "key": "menuItem3Link",
    "content": "/mobile/first-impressions.html"
}];

var obj = {};
var menu = data.map(function(v, k) {
    if (v.key.match(/menuItem\d*Title/) !== null) {
        obj = {
            title: v.content
        };
    } else if (v.key.match(/menuItem\d*Link/) !== null) {
        obj.link = v.content;
        return obj;
    }
});
menu = $.grep(menu, function(n) {
    return n == 0 || n
});

The code only works if the keys come in the exact order as shown in the OP.

Sign up to request clarification or add additional context in comments.

3 Comments

This works! Mind giving a quick explanation on how you've done it?
@mr_j, data is an array, so you can do data.map(function(v) { .... }); Just notice I didn't need the k. v each object in the original data. So we test the key, if title, then initialize the obj variable and set the title. If link, then set the link of the obj variable (at this point, it already has the title set). Then return the obj. This return statements returns the object in an array. When you run data.map, the return is an array of equal length. If you don't return anything, then you get undefined. Because of undefined, we use $.grep to filter out undefined.
Nice...was wondering what the $.grep was for. Thanks, have learnt a few tricks on looping arrays and objects
0

Try below code using for loop makes easier.. If your data is in the sequence as mentioned above

var data = {
  "menu":
  [    
    {
      "section":"theMobileMenu",
      "key":"menuItem1Title",
      "content":"Mobile context and principles"
    },
    {
      "section":"theMobileMenu",
      "key":"menuItem1Link",
      "content":"/mobile/index.html"
    },
    {
      "section":"theMobileMenu",
      "key":"menuItem2Title",
      "content":"Global guidelines"
    },
    {
      "section":"theMobileMenu",
      "key":"menuItem2Link",
      "content":"/mobile/global-guidelines.html"
    },
    {
      "section":"theMobileMenu",
      "key":"menuItem3Title",
      "content":"First impressions"
    },
    {
      "section":"theMobileMenu",
      "key":"menuItem3Link",
      "content":"/mobile/first-impressions.html"
    }
  ]
};

var newData = [];
var curData = {};
var menu = data.menu;

for(i=0, j=1; i < menu.length; i+=2, j++){
    if(menu[i]['key'] == "menuItem"+j+"Title"){
       curData.title = menu[i]['content'];       
       if($.isPlainObject(menu[i+1]) && menu[i+1]['key'] == "menuItem"+j+"Link"){
         curData.link = menu[i+1]['content'];       
       }
       newData.push(curData);
    }
    curData = {};
} 
console.log(newData);

Output :

[
   {
     "title":"Mobile context and principles",
     "link":"/mobile/index.html"
   },
  {
    "title":"Global guidelines",
    "link":"/mobile/global-guidelines.html"
  },
  {
    "title":"First impressions",
    "link":"/mobile/first-impressions.html"
  }
]

3 Comments

This returns a blank array
Please find below Fiddle URL
did you get the solution?
0

https://jsfiddle.net/VixedS/01x2a8jp/

var oldData = {menu:[{ "section": "theMobileMenus", "key": "menuItem1Title", "content": "Mobile context and principles" }, { "section": "theMobileMenu", "key": "menuItem1Link", "content": "/mobile/index.html" }, { "section": "theMobileMenu", "key": "menuItem2Title", "content": "Global guidelines" }, { "section": "theMobileMenu", "key": "menuItem2Link", "content": "/mobile/global-guidelines.html" }, { "section": "theMobileMenu", "key": "menuItem3Title", "content": "First impressions" }, { "section": "theMobileMenu", "key": "menuItem3Link", "content": "/mobile/first-impressions.html"}]};

var newData = []
$.each(oldData.menu, function(i, val){
    if (this.key.indexOf('Link') > -1)
        newData.push({'title':this.section,'link':this.content});
});

newData=JSON.stringify(newData);

Comments

0

This solution works for any order with a temporary object and some regular expressions for matching key, title and link.

var object = { menu: [{ "section": "theMobileMenu", "key": "menuItem1Title", "content": "Mobile context and principles" }, { "section": "theMobileMenu", "key": "menuItem1Link", "content": "/mobile/index.html" }, { "section": "theMobileMenu", "key": "menuItem2Title", "content": "Global guidelines" }, { "section": "theMobileMenu", "key": "menuItem2Link", "content": "/mobile/global-guidelines.html" }, { "section": "theMobileMenu", "key": "menuItem3Title", "content": "First impressions" }, { "section": "theMobileMenu", "key": "menuItem3Link", "content": "/mobile/first-impressions.html" }] },
    result = function (array) {
        var temp = {}
        array.forEach(function (a) {
            var k = a.key.match(/^menuItem\d*/);
            temp[k] = temp[k] || {};
            temp[k][a.key.match(/(Title)|(Link)$/)[0].toLowerCase()] = a.content;
        });
        return Object.keys(temp).map(function (k) { return temp[k]; });
    }(object.menu);

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.