0

I'm using Express JS and Mongo DB to build an API. I have entries in a collection to store various documents with data every day. My query pulls out data in the following format using toArray()

[
  {
    name: 'John',
    events: '600',
    created_at: '2021-01-20T14:56:42.368+00:00' // date object
  },
  {
    name: 'Edward',
    events: '900',
    created_at: '2021-01-20T20:56:42.368+00:00' // date object
  },
  {
    name: 'Jane',
    events: '100',
    created_at: '2021-01-19T13:56:42.368+00:00' // date object
  },
  {
    name: 'Robert',
    events: '700',
    created_at: '2021-01-19T15:56:42.368+00:00' // date object
  }
]

I need to get each object for the given date (grouped) and then get the newest one in that day, for example:

[
  {
    name: 'Edward',
    events: '900',
    created_at: '2021-01-20T20:56:42.368+00:00' // date object
  },
  {
    name: 'Robert',
    events: '700',
    created_at: '2021-01-19T15:56:42.368+00:00' // date object
  }
]

I've written a function to try this, but it's giving me the following type of format...

{
  'Tue Jan 19 2021 15:56:42 GMT+0000 (Greenwich Mean Time)': [
    {
      name: 'Robert',
      events: '700',
      created_at: '2021-01-19T15:56:42.368+00:00'
    }
  ]
}

How can I modify my function to achieve the desired results. Where am I going wrong?

function groupDataBeyondDaily (data, key = 'created_at') {
  const group = data.reduce((r, a) => {
    r[a.created_at] = [...r[a.created_at] || [], a]
    return r
  }, {})

  return group;
}
2
  • Okay... but that doesn't answer all of my question :) "I need to get each object for the given date (grouped) and then get the newest one in that day, for example" Commented Jan 22, 2021 at 14:32
  • Can you please provide an example on how the result data should look like? Do you want a group by date whereas each group only holds the most recent value or do you want to group by date for all values and then filter it afterwards? And which grouping criterion do you need? Is by date sufficient or do you need date and hour? Commented Jan 22, 2021 at 15:05

1 Answer 1

1

You are currently grouping them by the date strings stored in the created_at property, but you need to be grouping them by date and then comparing time of day separately.

The example snippet below creates a new Date() from the date string and calculates the epoch day to use as a key in the accumulator. It then compares the previously stored date against the current iteration and updates it if it is later. Finally, it returns the Object.values() of the object returned by the reduce() call.

const input = [{ name: 'John', events: '600', created_at: '2021-01-20T14:56:42.368+00:00' }, { name: 'Edward', events: '900', created_at: '2021-01-20T20:56:42.368+00:00' }, { name: 'Jane', events: '100', created_at: '2021-01-19T13:56:42.368+00:00' }, { name: 'Robert', events: '700', created_at: '2021-01-19T15:56:42.368+00:00' }];

function groupDataBeyondDaily(data) {
  const group = data.reduce((a, o) => {
    const
      date = new Date(o['created_at']),
      day = Math.floor(date / 8.64e7); // 86,400,000ms per day
    //let entry = (a[day] ??= { ...o }); using logical nullish assignment
    let entry = (a[day] = a[day] || { ...o });
    if (new Date(entry['created_at']) < date) {
      a[day] = { ...o };
    }
    return a
  }, {})

  return Object.values(group);
}

console.log(groupDataBeyondDaily(input))

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

Comments

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.