Recreator
@Recreator

Как найти ближайшую дату в массиве?

Приходит массив из которого надо выбрать ближайшую дату по принципу "сегодня или позже":
const Array = [
  {
    date: '01/01/2022',
    id: '1111',
  },
  {
    date: '31/03/2022',
    id: '2222',
  },
  {
    date: '23/05/2022',
    id: '3333',
  }
];
const findClosest = (data, accessor, target = Date.now()) =>
  data.reduce((prev, curr) => {
    const a = Math.abs(accessor(curr).getTime() - target);
    const b = Math.abs(accessor(prev).getTime() - target);
    return a - b < 0 ? curr : prev;
  });

const processDateString = (dateString) => {
  const [date, month, year] = dateString.split(/\//g).map(Number);
  return new Date(year, month - 1, date);
};

const closest = findClosest(Array, ({ date }) => processDateString(date));
const closestDate = closest.date;
console.log(closestDate);

возвращает ближайшую, но в прошлом.
Подскажите как переписать на "сегодня или позже"?
  • Вопрос задан
  • 480 просмотров
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
/**
 * My item definition
 * @typedef {Object} myItem
 * @property {string} date
 * @property {string} id
 */

/**
 * Find item with the date of today 
 * or the nearest one in the future
 * @param {myItem[]} data 
 * @returns {?myItem}
 */
const getNearest = data => {
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());

  const index = data
    .map(({date}, orginalIndex) => {
      const [d, m, y] = date.split('/');
      return { sorter: new Date(y, m - 1, d), orginalIndex };
    })
    .sort((a, b) => a.sorter - b.sorter)
    .find(item => item.sorter >= today)
    ?.orginalIndex;

  return data[index] || null;
}


// использование
const data = [
  { date: '01/01/2022', id: '1' },
  { date: '31/03/2022', id: '2' },
  { date: '23/05/2022', id: '3' },
  { date: '05/04/2022', id: '4' },
  { date: '03/04/2022', id: '5' },
  { date: '09/04/2022', id: '6' },
];

getNearest(data) // { date: "03/04/2022", id: "5" }
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
const parseDate = (date) => Date.parse(date.split('/').reverse().join('-'));
const findClosest = (list, date = (new Date()).toLocaleDateString('en-GB')) => {
  const findDate = parseDate(date);
  return list.reduce(
    (acc, cur) => {
      const delta = parseDate(cur.date) - findDate;
      return (delta >= 0 && delta < acc.delta) ? { delta, el: cur } : acc;
    },
    { delta: Number.MAX_SAFE_INTEGER, el: null },
  ).el;
};
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы