Home > Enterprise >  Unusual data grouping / transformation
Unusual data grouping / transformation

Time:10-01

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 }

  • Related