vinograd
vinograd

Reputation: 93

How to distribute objects into arrays depending on their date?

I ran into a problem that I don't know how to distribute objects based on their date. I would be very grateful for your help!

const arr = [
    { obj: 1, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 2, date: {day: '9', month: 'Jan', year: '2022'} },
    { obj: 3, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 4, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 5, date: {day: '9', month: 'Jan', year: '2022'} },
    { obj: 6, date: {day: '14', month: 'Oct', year: '2023'} },
];

The expected output:

[
  [
    { obj: 1, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 3, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 4, date: {day: '9', month: 'Oct', year: '2022'} },
  ],
  [
    { obj: 2, date: {day: '9', month: 'Jan', year: '2022'} },
    { obj: 5, date: {day: '9', month: 'Jan', year: '2022'} },
  ],
  [
    { obj: 6, date: {day: '14', month: 'Oct', year: '2023'} },
  ],
];

Upvotes: 3

Views: 120

Answers (2)

Hassan Imam
Hassan Imam

Reputation: 22534

You need to create a key based on the date object and make sure to convert the month-name into number. Now, you can group your data based on the key in an object accumulator and then extract values from this object using object.values().

const arr = [{ obj: 1, date: { day: '9', month: 'Oct', year: '2022' } }, { obj: 2, date: { day: '9', month: 'Jan', year: '2022' } }, { obj: 3, date: { day: '9', month: 'Oct', year: '2022' } }, { obj: 4, date: { day: '9', month: 'Oct', year: '2022' } }, { obj: 5, date: { day: '9', month: 'Jan', year: '2022' } }, { obj: 6, date: { day: '14', month: 'Oct', year: '2023' } }, ],
      monthLookup = { "Jan":"01","Feb":"02","Mar":"03","Apr":"04","May":"05","Jun":"06","Jul":"07","Aug":"08","Sep":"09","Oct":"10","Nov":"11","Dec":"12"},
      result = Object.values(arr.reduce((r, o) => {
        const key = o.date.year + '_' + monthLookup[o.date.month] + '_' + o.date.day;
        r[key] = r[key] || [];
        r[key].push(o);
        return r;
      },{}));
console.log(result);

Upvotes: 1

Kinglish
Kinglish

Reputation: 23654

You could use the date as an identifier to find the matches using Object.values() in a reduce iterator

const arr = [
    { obj: 1, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 2, date: {day: '9', month: 'Jan', year: '2022'} },
    { obj: 3, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 4, date: {day: '9', month: 'Oct', year: '2022'} },
    { obj: 5, date: {day: '9', month: 'Jan', year: '2022'} },
    { obj: 6, date: {day: '14', month: 'Oct', year: '2023'} },
];

let sorted = Object.values(arr.reduce((b, a) => {
  let val = Object.values(a.date).join('') // create the date identifier
  if (!b[val]) b[val] = []; // if we haven't used it yet, create it
  b[val].push(a); // add the object
  return b;
}, {}))

console.log(sorted)

Upvotes: 4

Related Questions