0

I have an array of objects for a podcast app that looks like this:

[{ id: "uuid-1"
   timeInSeconds: 1000
   dateListened: "2021-01-01T15:57:17.000Z" }, // <---same day
{  id: "uuid-2"
   timeInSeconds: 4900
   dateListened: "2021-01-01T16:57:17.000Z" }, // <---same day 
{  id: "uuid-3"
   timeInSeconds: 3200
   dateListened: "2021-09-01T16:57:17.000Z" }, 
{  id: "uuid-4"
   timeInSeconds: 6000
   dateListened: "2021-10-01T16:57:17.000Z" } ]

I want to create a function that combines activity times if the dateListened is on the same day. I want it to look something like this:

[{ id: "uuid-new" 
   timeInSeconds: 5900 // <---- combined seconds listened on Jan 1
   dateListened: "2021-01-01T15:57:17.000Z" },
{  id: "uuid-3"
   timeInSeconds: 3200
   dateListened: "2021-09-01T16:57:17.000Z" }, 
{  id: "uuid-4"
   timeInSeconds: 6000
   dateListened: "2021-10-01T16:57:17.000Z" } ]

My closest attempts have been to use a .map() with a nested .some() but I'm still far off enough that it's not even worth posting my tries. Does anyone have any hints or ideas of what direction to try next? Thank you!

3
  • 1
    So how much of this do you need help with? Do you just need a function like isSameDay(date1, date2) Commented Apr 20, 2021 at 23:39
  • your json is bad Commented Apr 20, 2021 at 23:43
  • There are plenty of dupes to choose from. Note that map wont work here because it always returns the same number of elements as is input. To change the number of outputs, you would generally use reduce. Commented Apr 20, 2021 at 23:45

2 Answers 2

1

You could reduce the items and map them to a date key, retrieve the values, and then map them to single objects.

You can key on the following:

let date = new Date(info.dateListened).toLocaleDateString('en-US')

const data = [
  { id: "uuid-1",
    timeInSeconds: 1000,
    dateListened: "2021-01-01T15:57:17.000Z" }, // <---same day
  { id: "uuid-2",
    timeInSeconds: 4900,
    dateListened: "2021-01-01T16:57:17.000Z" }, // <---same day 
  { id: "uuid-3",
    timeInSeconds: 3200,
    dateListened: "2021-09-01T16:57:17.000Z" }, 
  { id: "uuid-4",
    timeInSeconds: 6000,
    dateListened: "2021-10-01T16:57:17.000Z" }
 ];

const result = Object
  .values(data.reduce((acc, info) =>
    (date =>
      ({ ...acc, [date]: [...(acc[date] || []), info ] }))
    (new Date(info.dateListened).toLocaleDateString('en-US')), {}))
  .map(value => value.length === 1 ? value : {
    id: 'uuid-new',
    timeInSeconds: value.reduce((sum, { timeInSeconds }) => sum + timeInSeconds, 0),
    dateListened: value[0].dateListened
  });

console.log(result);
.as-console-wrapper { top: 0; max-height: 100% !important; }

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

Comments

0

You can achieve the result using reduce and only add the timeInSeconds if its year, month, and date is exactly the same/equal.

const arr = [
  {
    id: "uuid-1",
    timeInSeconds: 1000,
    dateListened: "2021-01-01T15:57:17.000Z",
  },
  {
    id: "uuid-2",
    timeInSeconds: 4900,
    dateListened: "2021-01-01T16:57:17.000Z",
  },
  {
    id: "uuid-3",
    timeInSeconds: 3200,
    dateListened: "2021-09-01T16:57:17.000Z",
  },
  {
    id: "uuid-4",
    timeInSeconds: 6000,
    dateListened: "2021-10-01T16:57:17.000Z",
  },
];

const result = arr.reduce((acc, curr) => {
  const { id, timeInSeconds, dateListened } = curr;
  const searchSameDateElement = acc.find((o) => {
    const first = new Date(o.dateListened);
    const second = new Date(dateListened);
    const isYearSame = first.getFullYear() === second.getFullYear();
    const isMonthSame = first.getMonth() === second.getMonth();
    const isDateSame = first.getDate() === second.getDate();
    return isYearSame && isMonthSame && isDateSame;
  });
  if (!searchSameDateElement) {
    acc.push(curr);
  } else {
    searchSameDateElement.timeInSeconds += timeInSeconds;
  }
  return acc;
}, []);

console.log(result);

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.