Donate. I desperately need donations to survive due to my health

Get paid by answering surveys Click here

Click here to donate

Remote/Work from Home jobs

Elegant way to filter array of dates, leaving only the first date in each month

If there is an array of dates in JS (ES7), which is the most elegant way of filtering it so that only the first date of each particular month stays?

For example, for input:

[
  "[native Date Mon Jan 04 2018 00:00:00]",
  "[native Date Thu Jan 10 2018 00:00:00]",
  "[native Date Thu Jan 27 2018 00:00:00]",
  "[native Date Sun Apr 01 2018 00:00:00]",
  "[native Date Tue Apr 03 2018 00:00:00]",
  "[native Date Fri Jun 15 2018 00:00:00]",
  "[native Date Mon Oct 02 2018 00:00:00]",
]

I'd like to get output:

[
    "[native Date Mon Jan 04 2018 00:00:00]",
    "[native Date Sun Apr 01 2018 00:00:00]",
    "[native Date Fri Jun 15 2018 00:00:00]",
    "[native Date Mon Oct 02 2018 00:00:00]",
]

It could be done by iterating (assume the array is sorted):

let datesFiltered = [];
for (let date of this.dates) {
    if (
        !datesFiltered.length ||
        date.getMonth() !== datesFiltered.slice(-1).pop().getMonth()
    ) {
        datesFiltered.push(date);
    }
}

or with array.filter — more concise, but seems to be necessary to use all three arguments to get previous element:

dates.filter(
    (element, index, array) =>
    index === 0 || element.getMonth() !== array[index - 1].getMonth()
);

or with array.reduce:

dates.reduce((accumulator, currentValue) => {
    if (
        !accumulator.length ||
        accumulator.slice(-1).pop().getMonth() !== currentValue.getMonth()
    ) {
        accumulator.push(currentValue);
    }
    return accumulator;
}, []);

Is there a more neat way to do this?

Comments