Home > OS >  how to convert an Array nested object into an Array object?
how to convert an Array nested object into an Array object?

Time:07-20

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; 
}))
  • Related