1

I'm struggling with converting the nested JSON array that I have.

{
  "Id": "1234",
  "Company": {
    "element": [{
      "Name": "htc",
      "Contacts": {
        "element": [{
          "name": "john",
          "phone": "1234"
        }, {
          "name": "peter",
          "phone": "5678"
        }]
      },
      "Address": {
        "element": {
          "country": "us",
          "state": "cali"
        }
      }
    }, {
      "Name": "samsung",
      "Contacts": {
        "element": [{
          "name": "luke",
          "phone": "0011"
        }, {
          "name": "james",
          "phone": "2233"
        }]
      },
      "Address": {
        "element": {
          "country": "us",
          "state": "texas"
        }
      }
    }]
  }
}

As you'll notice, there's this "element" in the arrays "Company", "Contacts" and "Address". But the output that I need to provide should not contain the "element" such as this code:

{
  "Id": "1234",
  "Company": [{
    "Name": "htc",
    "Contacts": [{
      "name": "john",
      "phone": "1234"
    }, {
      "name": "peter",
      "phone": "5678"
    }],
    "Address": [{
      "country": "us",
      "state": "cali"
    }]
  }, {
    "Name": "samsung",
    "Contacts": [{
      "name": "luke",
      "phone": "0011"
    }, {
      "name": "james",
      "phone": "2233"
    }],
    "Address": [{
      "country": "us",
      "state": "texas"
    }]
  }]
}

I have no clue how to do in JavaScript. Any ideas/tips are appreciate. Thank you

Rajesh
  • 24,354
  • 5
  • 48
  • 79
snorlax
  • 73
  • 8
  • You will have to loop over `elements` and manually create required structure – Rajesh Feb 01 '17 at 07:02
  • 1
    That's not JSON but a plain old object: [What is the difference between JSON and Object Literal Notation?](http://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) – Andreas Feb 01 '17 at 07:04

4 Answers4

0

The solution using Array.prototype.forEach() function:

var companyData = { "Id": "1234", "Company": { "element": [{ "Name": "htc", "Contacts": { "element": [{ "name": "john", "phone": "1234" }, { "name": "peter", "phone": "5678" }] }, "Address": { "element": { "country": "us", "state": "cali" } } }, { "Name": "samsung", "Contacts": { "element": [{ "name": "luke", "phone": "0011" }, { "name": "james", "phone": "2233" }] }, "Address": { "element": { "country": "us", "state": "texas" } } }] }
};

companyData.Company = companyData.Company.element;
var omitElement = function(o){
    if (!o['element']) return o;
    return (Array.isArray(o.element))? o.element : [o.element];
}
companyData.Company.forEach(function (o) {
    o.Contacts = omitElement(o.Contacts);
    o.Address = omitElement(o.Address);
});

console.log(companyData);
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
0

You can try something like this:

var data={Id:"1234",Company:{element:[{Name:"htc",Contacts:{element:[{name:"john",phone:"1234"},{name:"peter",phone:"5678"}]},Address:{element:{country:"us",state:"cali"}}},{Name:"samsung",Contacts:{element:[{name:"luke",phone:"0011"},{name:"james",phone:"2233"}]},Address:{element:{country:"us",state:"texas"}}}]}};

var keysToClean = ["Address", "Contacts"]

// Copy object instead of reference
var result = Object.assign({}, data);

result.Company = result.Company.element;
result.Company.forEach(x => {
  keysToClean.forEach(k => {
    x[k] = Array.isArray(x[k]) ? x[k].element : [x[k].element]
  })
})

console.log(result);

Note: I have use Object.create and Arrow functions. They are not supported by old browsers. You can refer to following link for alternative to deep copy an object:

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • don't you think comparing with an array `keys to Clean`, you are adding up an extra overhead. Simple if check will do it, Nah ? I mean in any case, it will loop through your keystoClean array. that's not efficient i guess. – Farooq Ahmed Khan Feb 01 '17 at 07:21
  • @FarooqKhan to add `if`, I will have to loop through all keys. Also I will have to hardcode all keys to parse in if like `if(k === a || k === b || k...)`. Instead having a mapping array would prove simpler. It will also reduce iterations from `O(3)` to `O(2)` in this case, but for a bigger object, this will be `O(n)` to `O(2)` which is better – Rajesh Feb 01 '17 at 07:25
  • Thanks @Rajesh. For Address, it also needs to be array (enclosed by [] like the Company and Contacts). How to achieve that? – snorlax Feb 01 '17 at 14:23
0

Please see this Plunker This should help.. it will generate desired result you need but be aware this is just a way to do this, and only meant for information purpose. It's not production grade...

function ParseData(data)
{
  var newObject={Id:0, Company:[]};

  newObject["Id"]=data["Id"];
  newObject["Company"]=CreateCompanyObject(data["Company"]["element"]);

  console.log(JSON.stringify(newObject));
}


function CreateCompanyObject(data)
{
  var companies=[];
 for(var i=0;i<data.length;i++)
 {
   companies.push({
                    name:data[i].Name, 
                    contacts:CreateContactObject(data[i].Contacts.element), 
                    Address:CreateAddressObject(data[i].Address.element)});

 };

  return companies;
}

function CreateContactObject(data){
  var contacts=[];
  for(var i=0;i<data.length;i++)
    contacts.push(data[i]);

  return contacts;
}

function CreateAddressObject(data){
  var address=[];
    if(typeof(data)=="array"){
    for(var i=0;i<data.length;i++)
    address.push(data[i]);
    }
    else
    address.push(data);

  return address;
}
ravi kant
  • 91
  • 2
0

You could check for element and move the content a step ahead to its parent.

function deleteElement(object){
    Object.keys(object).forEach(function (k) {
        if (object[k] && typeof object[k] === 'object') {
            if ('element' in object[k]) {
                object[k] = Array.isArray(object[k].element) ?
                    object[k].element :
                    [object[k].element];
            }
            deleteElement(object[k]);
        }
    });
}


var data = { Id: "1234", Company: { element: [{ Name: "htc", Contacts: { element: [{ name: "john", phone: "1234" }, { name: "peter", phone: "5678" }] }, Address: { element: { country: "us", state: "cali" } } }, { Name: "samsung", Contacts: { element: [{ name: "luke", phone: "0011" }, { name: "james", phone: "2233" }] }, Address: { element: { country: "us", state: "texas" } } }] } };

deleteElement(data);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392