Muhaimin CS
Muhaimin CS

Reputation: 305

Group array of object by some element followed by another element

I want to build a chat list where it grouped by unread messages followed by a date (in epoch format)

const myData = {
  "4072b701-a799-4951-be60-3f2d461bf482": {
    "id": "4072b701-a799-4951-be60-3f2d461bf482",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "Glad to connect!",
    "timestamp": "2019-06-18T04:30:56.188Z",
    "isOwner": false,
    "isRead": true
  },
  "1b2c0e15-a3b3-4994-8fda-e38e3cdc8d05": {
    "id": "1b2c0e15-a3b3-4994-8fda-e38e3cdc8d05",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "We have offices in San Jose, CA, Malaysia, Singapore and India",
    "timestamp": "2019-06-18T04:30:58.189Z",
    "isOwner": false,
    "isRead": true
  },
  "9613038a-b78a-4afe-aa2d-71d1a8292ec7": {
    "id": "9613038a-b78a-4afe-aa2d-71d1a8292ec7",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "Ask away, or select from below options",
    "timestamp": "2019-06-18T04:30:58.190Z",
    "isOwner": false,
    "isRead": true
  },
  "d409a190-6278-490b-9bf6-f3489b0a1cb5": {
    "id": "d409a190-6278-490b-9bf6-f3489b0a1cb5",
    "from": "b740849b-7553-4ddc-945e-b986aff854bb",
    "to": "BOT",
    "message": "this",
    "timestamp": "2019-06-18T04:32:55.356Z",
    "isOwner": true,
    "isRead": true
  },
  "acfc975f-f522-472d-a1f4-18a737da00f2": {
    "id": "acfc975f-f522-472d-a1f4-18a737da00f2",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "Glad to connect!",
    "timestamp": "2019-06-20T22:50:29.714Z",
    "isOwner": false,
    "isRead": false
  },
  "d409a190-6278-490b-9bf6-f3489b0a1cb5": {
    "id": "d409a190-6278-490b-9bf6-f3489b0a1cb5",
    "from": "b740849b-7553-4ddc-945e-b986aff854bb",
    "to": "BOT",
    "message": "this",
    "timestamp": "2019-06-21T04:32:55.356Z",
    "isOwner": true,
    "isRead": false
  },
};
const newObj = Object.keys(myData)
  .map(objId => myData[objId])
  .reduce((acc, value) => {
    const date = value.timestamp;
    if (!acc[date]) {
      acc[date] = [];
    }
    acc[date].push(value);

    return acc;
  }, {});

console.log(newObj);

As you can see I still have not sort the timestamp properly yet. So I missed to group the isRead flag and I really want the date variable in epoch format and only store the date

I expect the output like this

{
   read: {
     1489520157124: [{...}], // this is dummy epoch time
     1489520157154: [{...}]
   },
   unread: {
     1489520157124: [{...}], // this is dummy epoch time
     1489520157154: [{...}]
   }
}

Upvotes: 1

Views: 31

Answers (1)

Barmar
Barmar

Reputation: 781058

Add the read and unread properties to the accumulator object, and push the object onto the appropriate property.

Use Date.parse() to convert the timestamp to epoch time.

const myData = {
  "4072b701-a799-4951-be60-3f2d461bf482": {
    "id": "4072b701-a799-4951-be60-3f2d461bf482",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "Glad to connect!",
    "timestamp": "2019-06-18T04:30:56.188Z",
    "isOwner": false,
    "isRead": true
  },
  "1b2c0e15-a3b3-4994-8fda-e38e3cdc8d05": {
    "id": "1b2c0e15-a3b3-4994-8fda-e38e3cdc8d05",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "We have offices in San Jose, CA, Malaysia, Singapore and India",
    "timestamp": "2019-06-18T04:30:58.189Z",
    "isOwner": false,
    "isRead": true
  },
  "9613038a-b78a-4afe-aa2d-71d1a8292ec7": {
    "id": "9613038a-b78a-4afe-aa2d-71d1a8292ec7",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "Ask away, or select from below options",
    "timestamp": "2019-06-18T04:30:58.190Z",
    "isOwner": false,
    "isRead": true
  },
  "d409a190-6278-490b-9bf6-f3489b0a1cb5": {
    "id": "d409a190-6278-490b-9bf6-f3489b0a1cb5",
    "from": "b740849b-7553-4ddc-945e-b986aff854bb",
    "to": "BOT",
    "message": "this",
    "timestamp": "2019-06-18T04:32:55.356Z",
    "isOwner": true,
    "isRead": true
  },
  "acfc975f-f522-472d-a1f4-18a737da00f2": {
    "id": "acfc975f-f522-472d-a1f4-18a737da00f2",
    "from": "BOT",
    "to": "b740849b-7553-4ddc-945e-b986aff854bb",
    "message": "Glad to connect!",
    "timestamp": "2019-06-20T22:50:29.714Z",
    "isOwner": false,
    "isRead": false
  },
  "d409a190-6278-490b-9bf6-f3489b0a1cb5": {
    "id": "d409a190-6278-490b-9bf6-f3489b0a1cb5",
    "from": "b740849b-7553-4ddc-945e-b986aff854bb",
    "to": "BOT",
    "message": "this",
    "timestamp": "2019-06-21T04:32:55.356Z",
    "isOwner": true,
    "isRead": false
  },
};
const newObj = Object.values(myData)
  .reduce((acc, value) => {
    const date = Date.parse(value.timestamp);
    const prop = value.isRead ? "read" : "unread";
    if (!acc[prop][date]) {
      acc[prop][date] = [];
    }
    acc[prop][date].push(value);

    return acc;
  }, {read: {}, unread: {}});

console.log(newObj);

Upvotes: 1

Related Questions