pap
pap

Reputation: 115

Transform an array of objects into array of objects grouped by month and year

Hello I m trying to transform an array of object and group them by Month and Year. I have achieved the transformation and I get the months and years I need but then not all the items are going inside my groups.

My code:

const data = [
  {text:"Lorem 1 ipsum", date:"Thu Feb 21 2019 11:44:24 GMT+0000 (GMT)"},
  {text:"Lorem 2 ipsum", date:"Thu Feb 21 2019 11:44:24 GMT+0000 (GMT)"},
  {text:"Lorem 3 ipsum", date:"Thu Mar 21 2019 11:44:24 GMT+0000 (GMT)"},
]
const texts = [];
const formattedData = data.reduce((acc, { date, text }) => {
  const dateObj = new Date(date);
  const monthYearFormat = dateObj
    .toLocaleString("en-us", { month: "long", year: 'numeric' });

  if(acc[monthYearFormat]) {
    texts.push(text);

    acc[monthYearFormat] = {
      text: texts
    }
  } else {
    acc[monthYearFormat] = {
      text: [text]
    }
  }

  return acc;
}, {})

console.log(formattedData)

The result I get from this is:

{
  February 2019: {
   text: ['Lorem 2 ipsum']
  },
  March 2019: {
   text: ['Lorem 3 ipsum']
  }
}

It seems that it is replacing my first object though. The February should also contain "Lorem 1 ipsum" like so:

{
  February 2019: {
   text: ['Lorem 1 ipsum', 'Lorem 2 ipsum']
  },
  March 2019: {
   text: ['Lorem 3 ipsum']
  }
}

Any ideas where I m going wrong here? Thank you in advance.

Upvotes: 0

Views: 67

Answers (2)

gkelly
gkelly

Reputation: 288

Here's are two ways. The second is just for fun using reduce since your original code used reduce. Also, consider pushing the original object ( entry in this case ) so you not only have the text but the original date if needed.

const data = [
    { text: "Lorem 1 ipsum", date: "Thu Feb 21 2019 11:44:24 GMT+0000 (GMT)" },
    { text: "Lorem 2 ipsum", date: "Thu Feb 21 2019 11:44:24 GMT+0000 (GMT)" },
    { text: "Lorem 3 ipsum", date: "Thu Mar 21 2019 11:44:24 GMT+0000 (GMT)" },
];

let result = {};
data.forEach(entry => {
    let moyr = new Date(entry.date)
        .toLocaleString("en-us", { month: 'long', year: 'numeric' })
    result[moyr] = result[moyr] || { text: [] };
    result[moyr].text.push(entry.text);
});

console.log( result );

const data = [
    { text: "Lorem 1 ipsum", date: "Thu Feb 21 2019 11:44:24 GMT+0000 (GMT)" },
    { text: "Lorem 2 ipsum", date: "Thu Feb 21 2019 11:44:24 GMT+0000 (GMT)" },
    { text: "Lorem 3 ipsum", date: "Thu Mar 21 2019 11:44:24 GMT+0000 (GMT)" },
];

let result = data.reduce( (r,entry) => {
    let moyr = new Date(entry.date)
        .toLocaleString("en-us", { month: 'long', year: 'numeric' })
    r[moyr] = r[moyr] || { text: [] };
    r[moyr].text.push(entry.text);
    return r;
},{})

console.log( result );

Upvotes: 0

Charalampos Anargyrou
Charalampos Anargyrou

Reputation: 380

Instead of

if(acc[monthYearFormat]) {
  texts.push(text);

  acc[monthYearFormat] = {
    text: texts
  }
}

try

if(acc[monthYearFormat]) {
  acc[monthYearFormat].text.push(text);
}

Upvotes: 4

Related Questions