0

So I have an array with an x number of dates for example:

const dates= [date1, date2, date3, date4,...]

Where date1, date2, date3, date4 ... are all in Firebase timestamp date format. So I wanna be able to first convert each date into the day of the week (monday, tuesday...) and I also want to check if one date repeats, so (Monday, Tuesday, Monday, Wednesday, Wednesday) And if they do repeat id like to get the length of how many times they repeated, and the other ones that don't repeat I also want to get the length of those. I've tried doing a forEach like so,

dates.forEach(el=>{
    const days = ['Monday', 'Tuesday', 'Wednesday','Thursday', 'Friday', 'Saturday', 'Sunday']
    console.log(days[el.toDate().getDay()])
})

But get stuck here, don't really know how to compare if they are the same day. EDIT: I Realized that the date im using is in firebase timestamps

2

4 Answers 4

2

I found this to be the simplest way

The daysCount array index will represent each day with the number of days as the value:

const dates = [
  new Date('3/19/21'), // Friday
  new Date('4/12/21'), // Monday
  new Date('4/19/21'), // Monday
];

const daysCount = Array(7).fill(0);

dates.forEach(date => {
  const day = date.getDay();
  daysCount[day] += 1;
});

console.log(daysCount);

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

4 Comments

The trick with Array(7) and array index being the day value is nice 👍
Using reduce and given the OP has time values, not dates: dates.reduce((acc, date) => ++acc[new Date(date).getDay()] && acc, Array(7).fill(0));, which will also work if date is a Date. ;-)
@RobG The question says that it needs the day of the week and count them. Do we need to worry about the time values?
new Date(date) will work whether date is a Date or time value. You could finish the job by mapping the daysCount array to an object of {dayName:count}. :-)
1

Try the following code:

var dates = [new Date('03/09/1999'), new Date('12/29/1990')];
const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
  'Saturday', 'Sunday'
]

var daysOfWeek = dates.map(el => {
  return days[el.getDay()];
});

var counts = {};
daysOfWeek.forEach(function(x) {
  counts[x] = (counts[x] || 0) + 1;
});

// Including the days that do not appear
days.forEach(item => {
   if(!Object.keys(counts).includes(item)) {
     counts[item] = 0;
   }
});

console.log('All days: ', daysOfWeek);
console.log('Repeated times: ', counts);

2 Comments

Thanks, i have one more thing to add, would it be possible to fill add the days that are do not appear to have 0. So like {monday: 2, tuesday: 0, sunday: 1}etc
Yes it´s possible. I´ve edited my code to do that. Check it out.
0

Firstly, Date.getDay() returns 0 for Sunday, not Monday. But better yet, Intl.DateTimeFormat can be used to convert dates to day of the week as a string (e.g. 'Monday') as opposed to an int.

You're on the right track for iterating your dates, but you want array.map instead of forEach to map between dates and day of ht week.

You can then use array.reduce to count occurrances and array.sort to sort by occurances.

You'll see Object.entries and Object.fromEntries in my snippet; those convert between arrays and objects.

let dates = [new Date('3/19/21'), new Date('4/12/21'), new Date('4/19/21')];

let dayCounts = Object.fromEntries(Object.entries(dates
        .map(date =>
                new Intl.DateTimeFormat('en-US', {weekday: 'long'}).format(date))
        .reduce((counts, day) => {
            counts[day] = counts[day] || 0;
            counts[day]++;
            return counts;
        }, {}))
        .sort(([day1, count1], [day2, count2]) => count2 - count1));

console.log(dayCounts);

1 Comment

I realized that the date format is actually in firebase timestamp format, so im just getting saturday for all my dates
0

You could build a frequency map of localized date strings.

// Via: https://www.mockaroo.com/schemas/303013
const data = [{"id":1,"date":"2021-01-07T04:11:42Z"},{"id":2,"date":"2020-04-18T20:51:28Z"},{"id":3,"date":"2020-10-14T16:53:07Z"},{"id":4,"date":"2020-10-02T05:22:21Z"},{"id":5,"date":"2020-11-12T17:21:39Z"},{"id":6,"date":"2020-05-08T14:02:47Z"},{"id":7,"date":"2021-02-04T00:15:57Z"},{"id":8,"date":"2021-02-25T13:55:27Z"},{"id":9,"date":"2020-10-04T12:35:44Z"},{"id":10,"date":"2020-05-06T11:16:12Z"},{"id":11,"date":"2021-02-11T15:36:47Z"},{"id":12,"date":"2020-05-26T09:28:09Z"},{"id":13,"date":"2020-12-20T10:22:44Z"},{"id":14,"date":"2020-06-02T18:44:45Z"},{"id":15,"date":"2021-03-29T15:15:49Z"},{"id":16,"date":"2020-06-04T23:06:55Z"},{"id":17,"date":"2021-01-03T12:22:36Z"},{"id":18,"date":"2020-11-27T19:10:31Z"},{"id":19,"date":"2020-08-30T23:00:25Z"},{"id":20,"date":"2021-03-22T13:50:47Z"}];

const sortByValue = (obj, reverse = false) =>
  Object.fromEntries(Object.entries(obj).sort(([ ak, av ], [ bk, bv ]) =>
    (av - bv) * (reverse ? -1 : 1)));

const frequencyMap = data => data.reduce((acc, item) =>
  ({ ...acc, [item]: (acc[item] ?? 0) + 1 }), {});

const
  dates = data.map(({ date }) => date),
  daysOfWeek = dates.map(date => new Date(date).toLocaleDateString('en-US', { weekday: 'long' })),
  frequency = sortByValue(frequencyMap(daysOfWeek), true);

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

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.