1

I have this array of message objects and I wanted to group them that have similar from - to value or vice versa.

const msgs = [
  { id: '1', from: 'mimi', to: 'gudo', createdAt: '2021-01-01:T-50-249' }, //GROUP THIS
  { id: '5', from: 'gudo', to: 'mimi', createdAt: '2021-01-01:T-46-462' }, //

  { id: '2', from: 'john', to: 'gudo', createdAt: '2021-01-01:T-50-249' }, //GROUP THIS
  { id: '3', from: 'gudo', to: 'john', createdAt: '2021-01-01:T-46-462' }, //

  { id: '7', from: 'dave', to: 'gudo', createdAt: '2021-01-05' }, //GROUP THIS
]

This is my take to this, but there's still a problem, I have no clue how to append the obj that has no pair which is the object that has from property value of dave

let msg = [
  { id: '2', from: 'mimi', to: 'gudo', createdAt: '2021-01-01'},
  { id: '3', from: 'gudo', to: 'mimi', createdAt: '2021-01-02' },
  { id: '5', from: 'gudo', to: 'john', createdAt: '2021-01-03' },
  { id: '4', from: 'john', to: 'gudo', createdAt: '2021-01-05' },
  { id: '7', from: 'dave', to: 'gudo', createdAt: '2021-01-05' },
]

const sent = msg.filter(i => i.from === 'gudo');
const received = msg.filter(i => i.to === 'gudo');

const res = [];

for (let i = 0; i < sent.length; i++) {
   const curMine = sent[i];
   const pair = [];

   for (let j = 0; j < received.length; j++) {
      const curFrom = received[j];
      
      if(curMine.to === curFrom.from) {
        pair.push(curMine);
        pair.push(curFrom);
      } 
   }
   
   res.push(pair);
}

console.log(res)

Expected output:

[
  [
    { id: '2', from: 'mimi', to: 'gudo', createdAt: '2021-01-01'},
    { id: '3', from: 'gudo', to: 'mimi', createdAt: '2021-01-02' },
  ],
  [
    { id: '5', from: 'gudo', to: 'john', createdAt: '2021-01-03' },
    { id: '4', from: 'john', to: 'gudo', createdAt: '2021-01-05' },
  ],
  [
    { id: '7', from: 'dave', to: 'gudo', createdAt: '2021-01-05' }, // How to include this?
  ]
]
]

If you could help me or give an idea of a better way of doing this, I would be very grateful.

2 Answers 2

3

If you can come up with a way to uniquely identify a single key from a given combination of two participants (regardless of from or to), grouping into an object indexed by that key should be pretty easy.

I'd sort an array of the two properties alphabetically (and get, eg, ['gudo', 'mimi']), then pick a character that won't appear in the from or to properties, then join by that character (eg gudo#mimi). That can serve as the key. Then you just need to iterate over the array, and figure out the key for each item:

const msgs = [
  { id: '1', from: 'mimi', to: 'gudo', createdAt: '2021-01-01:T-50-249' }, //GROUP THIS
  { id: '5', from: 'gudo', to: 'mimi', createdAt: '2021-01-01:T-46-462' }, //

  { id: '2', from: 'john', to: 'gudo', createdAt: '2021-01-01:T-50-249' }, //GROUP THIS
  { id: '3', from: 'gudo', to: 'john', createdAt: '2021-01-01:T-46-462' }, //

  { id: '8', from: 'gudo', to: 'dave', createdAt: '2021-01-01:T-46-462' }, //GROUP THIS
]

const getKey = ({ from, to }) => [to, from]
  .sort((a, b) => a.localeCompare(b))
  .join('#');
const msgsByKey = {};
for (const msg of msgs) {
  const key = getKey(msg);
  if (!msgsByKey[key]) {
    msgsByKey[key] = [];
  }
  msgsByKey[key].push(msg);
}
console.log(Object.values(msgsByKey));

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

Comments

1

Basically you have to push the unprocessed entries to the pair list.

Below is a different approach.

let msg = [
  { id: '2', from: 'mimi', to: 'gudo', createdAt: '2021-01-01'},
  { id: '3', from: 'gudo', to: 'mimi', createdAt: '2021-01-02' },
  { id: '5', from: 'gudo', to: 'john', createdAt: '2021-01-03' },
  { id: '4', from: 'john', to: 'gudo', createdAt: '2021-01-05' },
  { id: '7', from: 'dave', to: 'gudo', createdAt: '2021-01-05' },
]

let p = [];
let processed = [];
msg.forEach(function(m) {
  if( processed.indexOf(m.id) >= 0 ) {
    return;
  }
  let filter = msg.filter(function(_m) {
    return m.from === _m.to && m.to === _m.from;
  });
  if( filter && filter.length) {
    p.push([m, filter[0]]);
    processed.push(m.id);
    processed.push(filter[0].id);
  } else {
    p.push(m);
    processed.push(m.id);
  }
});

console.error(p);

1 Comment

Really helpful! Thanks for the idea!

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.