I have an array:
let testData = [
{
MC: "11233",
jobid: 113331,
list: [
{ Q1: 1113, Q2: 333, code: "thisis1" },
{ Q1: 333, Q2: 111, code: "thisis2" },
{ Q1: 333, code: "thisis3" },
],
},
{
MC: "332211",
jobid: 3333,
list: [
{ Q1: 444, Q2: 555, code: "thisis4" },
],
},
];
And I want to convert it into:
[
{ MC: "11233", jobid: 113331, Q1: 1113, Q2: 333, code: "thisis1" },
{ MC: "11233", jobid: 113331, Q1: 333, Q2: 111, code: "thisis2" },
{ MC: "11233", jobid: 113331, Q1: 333, code: "thisis3" },
{ MC: "332211", jobid: 3333, Q1: 444, Q2: 555, code: "thisis4" },
]
I tried to write a recursive function like this
let newData = [];
testData.forEach((element, index) => {
let flattedObj = {};
deconstructeArrayObject(flattedObj, element);
});
and
const deconstructeArrayObject = (flattedObj, targetObj) => {
let tempArr = [];
for (let key in targetObj) {
if (Array.isArray(targetObj[key])) {
targetObj[key].forEach((element) => {
tempArr.push(
...JSON.parse(
JSON.stringify(
deconstructeArrayObject(flattedObj, element, outputArray)
)
)
);
});
} else {
flattedObj[key] = targetObj[key];
}
}
return flattedObj; // actually I want this function to return an array
};
I have no idea how should I reach my goal. Is there any hint or suggestion?
CodePudding user response:
Iterate the outer array, destructuring its properties, then do the same for each inner array, pushing the data you want in your result:
const input = [
{
MC: "11233",
jobid: 113331,
list: [
{ Q1: 1113, Q2: 333, code: "thisis1" },
{ Q1: 333, Q2: 111, code: "thisis2" },
{ Q1: 333, code: "thisis3" },
],
},
{
MC: "332211",
jobid: 3333,
list: [
{ Q1: 444, Q2: 555, code: "thisis4" },
],
},
];
const result = [];
for (const {MC, jobid, list} of input) {
for (const {Q1, Q2, code} of list) {
result.push(({MC, jobid, Q1, Q2, code}));
}
}
console.log(result);
CodePudding user response:
How about this:
let testData = [{"MC":"11233","jobid":113331,"list":[{"Q1":1113, "test": [{ 'a' : 1}, { 'a' : 2}],"Q2":333,"code":"thisis1"},{"Q1":333,"Q2":111,"code":"thisis2"},
{"Q1":333,"code":"thisis3"}]}
,{"MC":"332211","jobid":3333,"list":[{"Q1":444,"Q2":555,"code":"thisis4"}]}]
const deconstructeArrayObject = (targetObj) => {
let flattedObj = {};
let tempArr = [];
let arrayKeys = [];
for (let key in targetObj) {
// Save array keys
if (Array.isArray(targetObj[key])) {
arrayKeys.push(key);
} else {
flattedObj[key] = targetObj[key];
}
}
// flatten array elements
arrayKeys.forEach(key => {
targetObj[key].forEach((element) => {
const newEl = { ...flattedObj, ...element };
// Recursion
const arr = deconstructeArrayObject(newEl);
tempArr.push(...arr);
});
});
if(tempArr.length === 0) {
return [flattedObj];
}
return tempArr;
}
let newData = [];
testData.forEach((element, index) => {
const result = deconstructeArrayObject(element);
newData.push(...result)
});
console.log(newData)
The result will be:
[
{
"MC": "11233",
"jobid": 113331,
"Q1": 1113,
"Q2": 333,
"code": "thisis1",
"a": 1
},
{
"MC": "11233",
"jobid": 113331,
"Q1": 1113,
"Q2": 333,
"code": "thisis1",
"a": 2
},
{
"MC": "11233",
"jobid": 113331,
"Q1": 333,
"Q2": 111,
"code": "thisis2"
},
{
"MC": "11233",
"jobid": 113331,
"Q1": 333,
"code": "thisis3"
},
{
"MC": "332211",
"jobid": 3333,
"Q1": 444,
"Q2": 555,
"code": "thisis4"
}
]
CodePudding user response:
Here's a more general solution that doesn't depend on the specific key names, etc.
What you were missing was the answer to the subproblem: how do I merge multiple "deconstructed" objects in an array into my "flattedObj"?
This is done with the call to Object.assign
in the function below.
function deconstructeArrayObject(obj) {
const deconstructedObj = {};
for (const key in obj) {
if (Array.isArray(obj[key])) {
Object.assign(
deconstructedObj,
...obj[key].map(deconstructeArrayObject)
);
} else {
deconstructedObj[key] = obj[key];
}
}
return deconstructedObj;
}
// use like this
let newData = testData.map(deconstructeArrayObject);
CodePudding user response:
You try this code :
let result = testData.flatMap(data => data.list.map(el => {
let { list, ...rest } = data;
return { ...rest, ...el };
}));
CodePudding user response:
You could use Object.assing and create flattened array of new objects:
let testData = [
{
"MC":"11233",
"jobid":113331,
"list":[
{"Q1":1113,"Q2":333,"code":"thisis1"},
{"Q1":333,"Q2":111,"code":"thisis2"},
{"Q1":333,"code":"thisis3"}
]},
{
"MC":"332211",
"jobid":3333,
"list":[
{"Q1":444,"Q2":555,"code":"thisis4"}
]}
];
let result = testData.map(d1 => {
return d1.list.map(d2 => {
return Object.assign({ MC: d1.MC, jobid: d1.jobid }, d2)
});
}).flat();
console.log(result);
CodePudding user response:
Here is an approach using flatMap, that should return what you need.
testData.flatMap(job => job.list.map(item => {
item.MC = job.MC;
item.jobid = job.jobid;
return item;
}))