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>