Filter beween array elements

Viewed 43

I have an array of dates:

const dates = ['date1', 'date2', 'date3', 'date4', 'date5'];

and a function that gets two values and returns true if two dates are in same week

function isSameWeek(a,b){
// some code
 return true or false;
}

I want to filter the dates array in a way that none of it's values are in same week(one for each week).

For example if isSameWeek('date1', 'date2')=true , the filtered Array should be filtered=['date1', 'date3', 'date4', 'date5']

Helps are appreciated :)

2 Answers

You should check out Array's reduce method:

return dates.reduce((unique, date) => {
  if (unique.some(it => isSameWeek(it, date)) return unique;
  return [...unique, date];
}, [])

If the dates are sorted, this can be accomplished with a single pass:

// monkey patching here for example sake (ignore this)
Date.prototype.getWeekNumber = function() {
  var d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
  var dayNum = d.getUTCDay() || 7;
  d.setUTCDate(d.getUTCDate() + 4 - dayNum);
  var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
  return Math.ceil((((d - yearStart) / 86400000) + 1)/7);
}

const isSameWeek = (a, b) => a.getWeekNumber() == b.getWeekNumber();

function getWeeklyDates(dates)
{
  // can remove the sort() if already sorted
  dates.sort((a, b) => a - b)
  // filter out in a single pass
  return dates.filter((date, index) => {
    return index > 0 ? !isSameWeek(date, dates[index - 1]) : true; // not in the same week
  });
}

const dates = [
  new Date('2020-01-01'),
  new Date('2020-02-01'),
  new Date('2020-01-03'),
  new Date('2020-03-05'),
  new Date('2020-03-03')
];

console.log(getWeeklyDates(dates));

Related