1

I have parsed a CSV that slices like this:

data[0]
>>Date:08/23/2018, Organizer:RadioShack, Event:Promotion

I found a somewhat helpful question in: Find closest date in array with JavaScript, however I had trouble adapting it from an array of dates to dates stored within an array of objects. I have dates from data[0] to data[10]. It's not a terribly long dataset, however I would like to code it better than my current crude approach:

var dateArray = [];
dateArray[0] = data[0].Date;
dateArray[1] = data[1].Date;
…

console.log(dateArray.filter(function(d) {return d - today > 0; }))

That gives me all dates after today's date, which is a start, but I'm still falling short on finding the date closest to today.

Question: I thought maybe I could just write a for loop to give me that array faster, but I still wonder: is there a way I can find the date closest to today's date from an array of objects and store that date in:

var closestEventDate = ???
Arash Howaida
  • 2,575
  • 2
  • 19
  • 50

2 Answers2

8

You could reduce your dateArray to the date closest to today:

 const today = new Date();
 const closest = data.reduce((a, b) => a.Date - today < b.Date - today ? a : b);

Live Example:

var now = Date.now();
var ONE_DAY_IN_MS = 86400000;
function randomDate() {
  return new Date(now + (5 * ONE_DAY_IN_MS - Math.round(Math.random() * 10 * ONE_DAY_IN_MS)));
}
var data = [
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()}
];

console.log("Entries:");
data.forEach(function(entry) {
  console.log(entry.Date.toISOString());
});

const today = new Date();
const closest = data.reduce((a, b) => a.Date - today < b.Date - today ? a : b);

console.log("today", today.toISOString());
console.log("closest", closest.Date.toISOString());
.as-console-wrapper {
  max-height: 100% !important;
}

Or the closest after today:

const today = new Date();
const closest = data.reduce((a, b) => {
  const adiff = a.Date - today;
  return adiff > 0 && adiff < b.Date - today ? a : b;
});

Live Example:

var now = Date.now();
var ONE_DAY_IN_MS = 86400000;
function randomDate() {
  return new Date(now + (5 * ONE_DAY_IN_MS - Math.round(Math.random() * 10 * ONE_DAY_IN_MS)));
}
var data = [
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()},
  {Date: randomDate()}
];

console.log("Entries:");
data.forEach(function(entry) {
  console.log(entry.Date.toISOString());
});

const today = new Date();
const closest = data.reduce((a, b) => {
  const adiff = a.Date - today;
  return adiff > 0 && adiff < b.Date - today ? a : b;
});

console.log("today", today.toISOString());
console.log("closest", closest.Date.toISOString());
.as-console-wrapper {
  max-height: 100% !important;
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
1

In addition to Jonas' answer. Similar approach using dayjs library

arrayOfDates.reduce((a, b) => dayjs(a.Date).isAfter(dayjs(b.Date)) ? a : b);
Vlad R
  • 1,851
  • 15
  • 13