2

I am having difficulties formatting some data. Currently, I receive data in the following structure.

[
    {
       "q1":"5",
       "q2":[
          "13",
          "12",
       ],
       "q3":"test",
    }
]

I essentially need to modify this or even create a new object, that takes the following structure.

[
    {
      id: 1, //q1
      answers: [
        {
          answer: '5',
        },
      ],
    },
    {
      id: 2,  //q2
      answers: [
        {
          answer: '13',
        },
        {
          answer: '12',
        },
      ],
    },
    {
      id: 3,  //q3
      answers: [
        {
          answer: 'test',
        },
      ],
    },
];

So the id in the above would be obtained by remove the q and getting the number in the first data object. It would then have an answers array that would have an object for each answer.

I have been attempting this but have gotten lost. I don't know if I should use loops, mapping, filters etc. To be honest, the furthest I have got so far is obtaining the keys

var modified = data.map(function(item) {
  return Object.keys(item)
})

I have created a JSFiddle where I have been attempting to do this.

Is there any way I can achieve the data I am after?

Many thanks

4 Answers 4

4

Please use map function.

const data = {
   "q1":"5",
   "q2":[
      "13",
      "12",
   ],
   "q3":"test",
};

const result = Object.keys(data).map(key => {
    let item = {id: key.substring(1), answers: []};
    if(typeof data[key] === "string")
        item.answers.push({answer: data[key]});
    else
        item.answers = data[key].map(val => ({answer: val}));
    return item;
});

console.log(result)

Sign up to request clarification or add additional context in comments.

Comments

1

const inputData = [
    {
       "q1":"5",
       "q2":[
          "13",
          "12",
       ],
       "q3":"test",
    }
]

function answerMapper(objVal, id){
  return Array.isArray(objVal)
  ?
  { id, answers: objVal.map(answer => ({ answer }))}
  :
  { id, answers: [{answer: objVal }] }
}

function formatObject(obj){
  return Object.keys(obj).map((k, i)  => answerMapper(obj[k], i+1));
}

const result = inputData.map(obj => formatObject(obj));

// remove flatMap if your inputData has more than one entry
console.log(result.flatMap(x => x));

1 Comment

edited to increase readability
1

map over the first element of the data with Object.entries, grab the key and value, create a new answers array and return a new object.

const data = [{
  "q1": "5",
  "q2": [
    "13",
    "12",
  ],
  "q3": "test",
}];

const out = Object.entries(data[0]).map(obj => {

  const [ key, value ] = obj;
 
  const id = Number(key[1]);
  
  // If the the value is an array
  // return a new array of mapped data
  // Otherwise return an array containing
  // one object
  const answers = Array.isArray(value)
    ? value.map(el => ({ answer: el }))
    : [{ answer: value }];
  
  // Return the new object
  return { id, answers };

});

console.log(out);

Comments

1

lets create a pure function which accepts the object in the array like so

const processObject = obj => Object.keys(obj).map(id => {
const answer = obj[id];

const answers = Array.isArray(answer) ? answer : [answer]
const answerObjectArray = answers.map(ans => ({
    answer: ans
}));

return {
    id: +id.substring(1),
    answers: answerObjectArray
    
}
});


const dataArray = [{
"q1": "5",
"q2": [
    "13",
    "12",
],
"q3": "test",
}];
const output = processObject(dataArray[0]);

console.log(output);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.