kumaran
kumaran

Reputation: 366

Sort and Group Array of JS Objects by DateTime Field

I am creating one chat application. In which, I want to group by date(1 min) if current message is coming lesser than 1 min previous message i want to group by with older one

var message = [
    {
      "dateString": "2020-06-03 07:21:03",
      "msgid": "13975aafbc5345f4a9bdea3676f19b961591168852",
      "msgtype": "image"
    },
    {
      "dateString": "2020-06-03 07:21:00",
      "msgid": "76a0e07d504d41239b60b91f04308d9f1591168851",
      "msgtype": "image"
    },
    {
      "dateString": "2020-06-03 07:20:57",
      "msgid": "ff7a9fd28d82431384029da637d8b1a41591168851",
      "msgtype": "image"
    },
    {
      "dateString": "2020-06-03 07:20:57",
      "msgid": "810bca0b5fef4e1894f97c63984c15b91591168852",
      "msgtype": "image"
    },
    {
      "dateString": "2020-06-03 02:13:12",
      "msgid": "40f9db43a8ca4d51bcb63d24b0080b711591150390",
      "msgtype": "text"
    }
]

i tried something like this :

var isFromGreaterThanTo = (dtmfrom, dtmto) => dtmfrom.getTime() >= dtmto.getTime();

var groupBy = (messageToGroup, callback) => {
    return messageToGroup.reduce((groups, message) => {
        const currentIndex = Object.keys(groups)[Object.keys(groups).length-1];
        const previousElement = currentIndex && groups 
        const { dateString = null } = previousElement || { }
        const date = callback(message.dateString, dateString)
        groups[date] = [...groups[date] || [], message];
        return groups;
    }, {});
}

var groupedMessages = groupBy(message, (date, previousDate) => {
    if(!previousDate) return date.replace(/:[^:]*$/,'');
    const previousObject = new Date(previousDate);
    previousObject.setTime(previousObject.getTime() - 1000 * 60);
    const updateDate =  isFromGreaterThanTo(new Date(date),previousObject) ? date : previousDate;
    return updateDate.replace(/:[^:]*$/,'')
});

Upvotes: 0

Views: 173

Answers (1)

Dmitry Reutov
Dmitry Reutov

Reputation: 3032

just use reduce function and create new array each time when first element of current array will be more than 60000 milliseconds of next record

const { res } = message
  .sort((a, b) => b.dateString > a.dateString ? 1 : -1)
  .reduce((agg, v) => {
     const time = new Date(v.dateString).getTime()
     if (!agg.currentTime || (agg.currentTime - time > 60000)) {
       agg.currentArray = [] 
       agg.res.push(agg.currentArray)
       agg.currentTime = time
     } 
     agg.currentArray.push(v)
     return agg
   }, { res: [] })

console.log(res)

Upvotes: 1

Related Questions