Home > front end >  Combine consecutive objects in an array to form a new array
Combine consecutive objects in an array to form a new array

Time:02-18

This is my sample array. Array length can be n

[{
"name": "question",
"value": "this is a first question"
},
{
"name": "answer",
"value": "this is a frist answer"
},
{
"name": "question",
"value": "this is a second question"
},
{
"name": "answer",
"value": "this is a second answer"
}
]

I want the following output by combining two consecutive objects.

[{"question":"This is first question", "answer":"This is first answer"}, {"question":"This is second question", "answer":"This is second answer"}]

What should be my javascript to achieve the same? I am stuck here for the last 2 days

CodePudding user response:

You can try with something similar:

let data = [{
"name": "question",
"value": "this is a first question"
},
{
"name": "answer",
"value": "this is a frist answer"
},
{
"name": "question",
"value": "this is a second question"
},
{
"name": "answer",
"value": "this is a second answer"
}
];

let newData = [];
for(let i=0,l=data.length;i<l;i=i 2) {
  newData.push({
    question:data[i].value,
    answer: (data[i 1]||{}).value
  });
}

console.log(newData);

CodePudding user response:

Convert the array into one with two-element sub-arrays using map() and filter() methods, then convert the sub-arrays into objects using reduce method.

const exam = [{
        "name": "question",
        "value": "this is a first question"
    },
    {
        "name": "answer",
        "value": "this is a frist answer"
    },
    {
        "name": "question",
        "value": "this is a second question"
    },
    {
        "name": "answer",
        "value": "this is a second answer"
    }
];

const newExam = exam
//map each odd element to a two-element sub-array; even []
.map((q,i,a) => i % 2 === 0 ? [q,a[i 1]] : [])
//filter out []
.filter(q => q.length)
//convert each sub-array into an object
.map( q => q.reduce((qn,{name,value}) => ({...qn,[name]:value}), {}) );

console.log( newExam );

Using reduce() instead of map() and filter()

const exam = [{
        "name": "question",
        "value": "this is a first question"
    },
    {
        "name": "answer",
        "value": "this is a frist answer"
    },
    {
        "name": "question",
        "value": "this is a second question"
    },
    {
        "name": "answer",
        "value": "this is a second answer"
    }
];

const newExam = exam
//convert array into two-element sub-arrays
.reduce((ex,q,i,a) => i % 2 === 0 ? [...ex,[q,a[i 1]]] : ex, [])
//convert each sub-array into an object
.map( q => q.reduce((qn,{name,value}) => ({...qn,[name]:value}), {}) );

console.log( newExam );

Using just reduce()

const exam = [{
        "name": "question",
        "value": "this is a first question"
    },
    {
        "name": "answer",
        "value": "this is a frist answer"
    },
    {
        "name": "question",
        "value": "this is a second question"
    },
    {
        "name": "answer",
        "value": "this is a second answer"
    }
];

const newExam = exam
.reduce(
    (ex,{name,value},i,a) => 
    i % 2 === 0 ? [...ex,{[name]:value,[a[i 1].name]:a[i 1].value}] : ex, []
);

console.log( newExam );

  • Related