В массиве дат, как найти ближайшую предыдущую дату от данной даты (javascript)? - PullRequest
0 голосов
/ 28 марта 2020

У меня есть массив с датами с интервалом в три дня, т. Е. 10 февраля, 13 февраля, 16 февраля и т. Д.

var givenDate = new Date();

givenDate.setDate(12);

In В приведенном выше массиве я хочу найти ближайшую предыдущую дату из данного значения - поэтому ответ должен быть 10 февраля (поскольку это ближайшая предыдущая дата к 12 февраля).

Я нашел это на одном из форумов чтобы получить ближайшую дату:


var bestDate = dates.length; // dates is the name of my array

var bestDiff = -(new Date(0,0,0)).valueOf();

var currDiff = 0;

var i;

for(i = 0; i < dates.length; ++i){

   currDiff = Math.abs(between[i] - testDate);

   if(currDiff < bestDiff){

       bestDate = i;

       bestDiff = currDiff;

   }   
}

// the best date will be days[bestDate] 

document.write(dates[bestDate]);

Проблема в том, что она дает ближайшую дату, которая может быть следующей, а не предыдущей. Как и 12 февраля, вместо 10 февраля будет 13 февраля.

Спасибо.

Ответы [ 4 ]

2 голосов
/ 28 марта 2020

1) Сортировка в обратном порядке, чтобы (16-е место было первым и 10-е последним из дат выборки)
2) Использовать метод find для отсортированного выше массива, чтобы получить ближайшую предыдущую дату в доступных датах.

Обновление: спасибо @RobG, это приятно знать.
@Masoom, вместо find используйте findIndex, чтобы получить индекс даты. Тогда вы можете легко следующий. PS. Вам нужно будет убедиться в крайних случаях и доступе из связанных индексов. (findIndex вернет -1, если не найден или когда предыдущая дата равна 0 index, то на следующий день не будет)

const dates = [
  new Date(2020, 1, 10),
  new Date(2020, 1, 13),
  new Date(2020, 1, 16)
];

const my_date = new Date(2020, 1, 12);

const prev_date_index = dates
  .sort((a, b) => (b - a))
  .findIndex(date => date - my_date <= 0);
  
const prev_date = dates[prev_date_index];
const next_date = dates[prev_date_index - 1];

console.log(prev_date.toDateString());
console.log(next_date.toDateString());
1 голос
/ 28 марта 2020
  • Сортировка
  • getIndex и получение значения

var datesArray = [new Date("02-10-2020"), new Date("02-13-2020"), new Date("02-16-2020")];

var newDateToInsert = new Date("02-12-2020");
datesArray.push(newDateToInsert);

datesArray.sort((a, b) => a - b);
var index = (datesArray.indexOf(newDateToInsert) - 1) >= 0 ? datesArray.indexOf(newDateToInsert) - 1 : datesArray.indexOf(newDateToInsert);
console.log(datesArray[index]);

---- EDIT ----
вы можете клонировать это также в новом массиве, что-то вроде приведенного ниже, чтобы не изменять исходный массив-

var datesArray = [new Date("02-10-2020"), new Date("02-13-2020"), new Date("02-16-2020")];

var newDateToInsert = new Date("02-12-2020");
var tempArray = [].concat(datesArray);
tempArray.push(newDateToInsert);

tempArray.sort((a, b) => a - b);
var index = (tempArray.indexOf(newDateToInsert) - 1) >= 0 ? tempArray.indexOf(newDateToInsert) - 1 : tempArray.indexOf(newDateToInsert);
console.log(datesArray[index]);
1 голос
/ 28 марта 2020

Код, который вы выбрали, не подходит по той причине, о которой вы заявляете, и ваше решение может быть намного проще. Вы хотите найти последнюю дату, которая предшествует вашей дате, поэтому просто вычтите каждую дату из контрольной даты, а когда результат будет 0 или отрицательным, вам нужна предыдущая дата.

Вам также следует иметь дело с выходящими за пределы значениями, например, до начала или после конца. Я угадал, что вы хотите в этих случаях, вам нужно подумать, что нужно сделать, и настроить лог c в соответствии.

Например

// Get last element of arr that is before d
function getPrevious(d, arr) {
  let i = 0;
  while (d - arr[i] > 0 && i < arr.length - 1) {
    i++;
  }
  return i == 0? void 0 : arr[--i] ;
}

// Sample data
let dates = [
  new Date(2020, 1, 10), // 2020-02-10
  new Date(2020, 1, 13), // 2020-02-13
  new Date(2020, 1, 16), // 2020-02-16 
  new Date(2020, 1, 19)  // 2020-02-19
];

// Test dates
[new Date(2020, 1,  8), // 2020-02-08 -> before start -> undefined
 new Date(2020, 1, 12), // 2020-02-12 -> within range -> 10 Feb
 new Date(2020, 2, 12)  // 2020-03-12 -> after end    -> last date
].forEach(d => {
  let result = getPrevious(d, dates);
  console.log(`${d.toDateString()} -> ${result? result.toDateString() : result}`)
});
0 голосов
/ 28 марта 2020

Привет,

Решение

let dates = // --> your dates array
let givenDate = new Date();
let givenDateInMS = givenDate.getTime();

let prevTimeDiff = Infinity;
let closestDate = null;
dates.forEach((date, index) => {
 let timeInMS = date.getTime();
 let timeDiff = givenDateInMS - timeInMS;
 if((timeDiff > 0) && (timeDiff < prevTimeDiff)) {
    prevTimeDiff = timeDiff;
    closestDate = date;
 }
})

if(closestDate != null){
 // here you have it
 console.log(closestDate)
}else{
 //there is no prev closest date (all dates might be greater than given date)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...