Home > Net >  Converting an array of data to JSON using a property map
Converting an array of data to JSON using a property map

Time:12-06

I am trying to convert a 2d array into a json object using a key map. The key map looks like

var keys = ['id', 'title', 'customer.id', 'customer.name', 'customer.phone.home', 'customer.phone.mobile' ];

and the data is

var data = [
  [1, 'Task 1', 'C1', 'Customer 1', '999', '8888'],
  [2, 'Task 2', 'C2', 'Customer 2', '333', '5555']
];

Output JSON should be

    var output = [
   {
      "id":1,
      "title":"Task 1",
      "customer":{
         "id":"C1",
         "name":"Customer 1",
         "phone":{
            "home":"999",
            "mobile":"8888"
         }
      }
   },
   {
      "id":2,
      "title":"Task 2",
      "customer":{
         "id":"C2",
         "name":"Customer 2",
         "phone":{
            "home":"333",
            "mobile":"5555"
         }
      }
   }
];

I am trying to do it something like but I am not good here making smerecursion etc. Could anyone help please?

function arrToJSON(headers, data){
  var output = [];
  data.forEach(row, index){
    var cObj = {};
    headers.forEach(header, itemIndex){
      var headerParts = header.split('.');
      // NOt sure what to do here
    }
  }
}

CodePudding user response:

You can easily achieve the result using map and reduce in js.

createObj(acc, curr.split("."), 0, o[index]);

is the function that is used in recursion and that is what you're looking for.

Arguments

createObj(
      acc,                  // object in which you want to add value
      curr.split("."),      // send path as an array
      0,                    // current index in path, initially zero
      o[index]              // value to be assigned
    );

var keys = [
  "id",
  "title",
  "customer.id",
  "customer.name",
  "customer.phone.home",
  "customer.phone.mobile",
];

var data = [
  [1, "Task 1", "C1", "Customer 1", "999", "8888"],
  [2, "Task 2", "C2", "Customer 2", "333", "5555"],
];

function createObj(obj, arr, index, value) {
  if (index === arr.length - 1) obj[arr[index]] = value;
  else {
    if (!obj[arr[index]]) obj[arr[index]] = {};
    createObj(obj[arr[index]], arr, index   1, value);
  }
}

const result = data.map((o) => {
  return keys.reduce((acc, curr, index) => {
    createObj(acc, curr.split("."), 0, o[index]);
    return acc;
  }, {});
});

console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */

.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You can use simply use destructure and spread operator with reduce.

var data = [
  [1, "Task 1", "C1", "Customer 1", "999", "8888"],
  [2, "Task 2", "C2", "Customer 2", "333", "5555"],
];

const buildObject = (arr = []) => {
  return arr.reduce((acc, [id, title, cid, name, home, mobile]) => {
    const row = {
      id,
      title,
      customer: { id: cid, name, phone: { home, mobile } },
    };
    return acc.concat(row);
  }, []);
};

console.log(buildObject(data));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related