skip to Main Content

I have a json where I need to reduce the items when they are of a type (isSender).
I need to reduce them when they are occurring consecutively.
The data can change.

The data looks like this:

 "messages": [
    { "content": ["Foo"], "isSender": true },
    { "content": ["Bar"], "isSender": true },
    { "content": ["Lorem"], "isSender": true },
    { "content": ["Ipsum"], "isSender": true },
    { "content": ["Dolor"], "isSender": false },
    { "content": ["Sit Amet"], "isSender": false },
    { "content": ["No"], "isSender": true }
  ]

I need the content to be an array of messages when the consecutive isSender key is the same. The output should look like this:

  "messages": [
    {
      "content": ["Foo", "Bar", "Lorem", "Ipsum"],
      "isSender": true
    },
    { "content": ["Dolor", "Sit amet"], "isSender": false },
    { "content": ["No"], "isSender": true }
  ]

So far I have tried looping through the message array and checking if next messages have the same isSender key. However this does not work for more than 2 messages.

let deleteIndex = [];
 for(let i = 0  ; i < messages.length - 1; i++) {
        const currMs = messages[i];
        const nextMs = messages[i + 1];
        if (nextMs.isSender == currMs.isSender) {
            currMs.content.push(nextMs)
            deleteIndex.push(i + 1) // saving index to be deleted once for loop is done
        }
    }

Can someone give me a clue on how to work around this?

Thanks in advance.

2

Answers


  1. you can try this

    var res = {
      messages: [
        { content: [], isSender: true },
        { content: [], isSender: false },
        { content: [], isSender: false }
      ]
    };
    
    messages.messages.forEach((item) => {
      if (item.content[0] == "No")  {
    res.messages[2].content = ["No"];
    res.messages[2].isSender = item.isSender;
      }
      else {
        if (item.isSender)
           res.messages[0].content.push(...item.content);
        else res.messages[1].content.push(...item.content);
      }
    });
    
    console.log(JSON.stringify(res, null, 4));
    

    json output

    {
      "messages": [
        {
          "content": [
            "Foo",
            "Bar",
            "Lorem",
            "Ipsum"
          ],
          "isSender": true
        },
        {
          "content": [
            "Dolor",
            "Sit Amet"
          ],
          "isSender": false
        },
        {
          "content": [
            "No"
          ],
          "isSender": true
        }
      ]
    }
    
    Login or Signup to reply.
  2. Use reduce(), on each iteration, we check if the last element in the result array has the same isSender value as the current object we’re dealing with.

    if (p.length && p.at(-1).isSender === c.isSender) {
    

    So, if we already have something in the final array (p.length) AND the last isSender (p.at(-1).isSender) has the same value as the current isSender (c.isSender), append to that content list

    Otherwise, add the entry, which is just the current object itself (return [ ...p, c ])

    const data =  [
        { "content": ["Foo"], "isSender": true },
        { "content": ["Bar"], "isSender": true },
        { "content": ["Lorem"], "isSender": true },
        { "content": ["Ipsum"], "isSender": true },
        { "content": ["Dolor"], "isSender": false },
        { "content": ["Sit Amet"], "isSender": false },
        { "content": ["No"], "isSender": true }
      ];
      
    const res = data.reduce((p, c) => {
        if (p.length && p.at(-1).isSender === c.isSender) {
            p.at(-1).content.push(...c.content);
            return p;
        }
        return [ ...p, c ];
    }, [])
    
    console.log(res);

    Should you not like the push way, we can use Object.assign to alter the index itself:

    let i = p.length - 1;
    return Object.assign([...p], { [i]: { ...p[i], content: [ ...p[i].content, ...c.content ]}});
    
    const data =  [
        { "content": ["Foo"], "isSender": true },
        { "content": ["Bar"], "isSender": true },
        { "content": ["Lorem"], "isSender": true },
        { "content": ["Ipsum"], "isSender": true },
        { "content": ["Dolor"], "isSender": false },
        { "content": ["Sit Amet"], "isSender": false },
        { "content": ["No"], "isSender": true }
      ];
      
    const res = data.reduce((p, c) => {
        if (p.length && p.at(-1).isSender === c.isSender) {
            let i = p.length - 1;
            return Object.assign([...p], { [i]: { ...p[i], content: [ ...p[i].content, ...c.content ]}});
        }
        return [ ...p, c ];
    }, [])
    
    console.log(res);

    Javascript spread on array index to 'push' new item to nested array


    [
      {
        "content": ["Foo", "Bar", "Lorem", "Ipsum"],
        "isSender": true
      },
      {
        "content": ["Dolor", "Sit Amet"],
        "isSender": false
      },
      {
        "content": ["No"],
        "isSender": true
      }
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search