I'm struggling with an algorithmic problem how go transform or group data to get specified output.
My input is a bunch of messages in given order (from newest to oldest):
[
{
"id":5,
"created_at":"2021-01-01 00:00:00",
"message":"Lorem ipsum dolor sit amet...",
"is_author":true,
"meta_data":{
}
},
{
"id":4,
"created_at":"2021-01-01 01:00:00",
"message":"Lorem ipsum dolor sit amet...",
"is_author":true,
"meta_data":{
}
},
{
"id":3,
"created_at":"2021-01-01 03:00:00",
"message":"Lorem ipsum dolor sit amet...",
"is_author":false,
"meta_data":{
}
},
{
"id":2,
"created_at":"2021-01-01 04:00:00",
"message":"Lorem ipsum dolor sit amet...",
"is_author":false,
"meta_data":{
}
},
{
"id":1,
"created_at":"2021-01-01 05:00:00",
"message":"Lorem ipsum dolor sit amet...",
"is_author":true,
"meta_data":{
}
},
{
"id":0,
"created_at":"2021-01-01 06:00:00",
"message":"Lorem ipsum dolor sit amet...",
"is_author":false,
"meta_data":{
}
}
]
Desired output after transformation:
[
{
"is_author":true,
"messages":[
{
"id":5,
"created_at":"2021-01-01 00:00:00",
"message":"Lorem ipsum dolor sit amet...",
"meta_data":{
}
},
{
"id":4,
"created_at":"2021-01-01 01:00:00",
"message":"Lorem ipsum dolor sit amet...",
"meta_data":{
}
}
]
},
{
"is_author":false,
"messages":[
{
"id":3,
"created_at":"2021-01-01 03:00:00",
"message":"Lorem ipsum dolor sit amet...",
"meta_data":{
}
},
{
"id":2,
"created_at":"2021-01-01 04:00:00",
"message":"Lorem ipsum dolor sit amet...",
"meta_data":{
}
}
]
},
{
"is_author":true,
"messages":[
{
"id":1,
"created_at":"2021-01-01 05:00:00",
"message":"Lorem ipsum dolor sit amet...",
"meta_data":{
}
}
]
},
{
"is_author":false,
"messages":[
{
"id":0,
"created_at":"2021-01-01 06:00:00",
"message":"Lorem ipsum dolor sit amet...",
"meta_data":{
}
}
]
}
]
So as you can see, each occurrence of the is_author parameter creates a new group that collects messages from this author ?
Is there any efficient solution in JS or PHP to transform such data?
CodePudding user response:
const data=[{"id":5,"created_at":"2021-01-01 00:00:00","message":"Lorem ipsum dolor sit amet...","is_author":true,"meta_data":{}},{"id":4,"created_at":"2021-01-01 01:00:00","message":"Lorem ipsum dolor sit amet...","is_author":true,"meta_data":{}},{"id":3,"created_at":"2021-01-01 03:00:00","message":"Lorem ipsum dolor sit amet...","is_author":false,"meta_data":{}},{"id":2,"created_at":"2021-01-01 04:00:00","message":"Lorem ipsum dolor sit amet...","is_author":false,"meta_data":{}},{"id":1,"created_at":"2021-01-01 05:00:00","message":"Lorem ipsum dolor sit amet...","is_author":true,"meta_data":{}},{"id":0,"created_at":"2021-01-01 06:00:00","message":"Lorem ipsum dolor sit amet...","is_author":false,"meta_data":{}}];
const result = data.reduce((acc, item) => {
const { is_author, ...rest } = item;
// if is_author match with previous object
if(acc.length && acc[acc.length-1].is_author === is_author){
// copy previous messages, along with current item
acc[acc.length-1].messages = [...acc[acc.length-1].messages, rest ];
}else{
acc.push({ is_author, messages: [ rest ] });
}
return acc;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }