Сортировка Vuetify v-data-table по датам в строковом формате и потенциальным нулям

У меня есть таблица v-данных, которая включает даты, отформатированные с помощью DayJS до «ММ/ДД/ГГГГ», однако некоторые даты имеют значение null, поскольку они еще не завершены. Я пытаюсь добавить сортировку в массив заголовков для этого форматированного столбца даты:

        { title: 'Memo Date', key: 'memo_date', align: 'center', visible: true, filtered: [], sort: 
      function(a: string, b: string) {
        if (a == null && b == null) 
        {
          let c = dayjs().format("MM/DD/YYYY")
          console.info(c)

          return 0
        }
        else if (a == null) {
          let c = dayjs().format("MM/DD/YYYY")
          console.info(c)
          return (dayjs(c).diff(dayjs(b)))
        } else if (b == null) 
        {
          let c = dayjs().format("MM/DD/YYY")
          console.info(c)
          return (dayjs(a).diff(dayjs(c)))
        }
        return dayjs(a).diff(dayjs(b))
      }
    },

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

ОБНОВЛЯТЬ: Основываясь на недавнем ответе, я опубликовал потенциальное использование для сортировки, но по-прежнему нулевые даты отображаются как более ранние даты, тогда как я хочу, чтобы они считались самыми новыми датами:

const customDateSort = (a : string, b : string) => {
  const aDate = String((new Date(a)).getTime())
  const bDate = String((new Date(b)).getTime())
  return aDate.localeCompare(bDate)
}

Почему бы не преобразовать его в метку времени?

kissu 30.05.2024 18:46

Как бы это можно было сравнить? Можете ли вы указать, о чем вы говорите в ответе?

Qiuzman 30.05.2024 18:54

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

Hitesh Lala 30.05.2024 19:00

Отфильтруйте первые даты, чтобы удалить нулевые. Что-то вроде dates.filter(date -> !date) Вы также можете использовать два разных массива: один с нулевыми датами и один с заполненными датами.

kissu 30.05.2024 19:13

Проблема с фильтрацией заключается в том, что эти значения по-прежнему должны отображать пустые даты в таблице v-данных. Сортировка в заголовке v-data-table сортирует массив элементов.

Qiuzman 30.05.2024 19:15

Подождите, вы сказали, что некоторые даты имеют значение null, но вы можете указать текущую дату? Почему бы тогда не использовать это? Вы перемещаете новый массив с помощью .map или же вы находите значения null, заменяете их на new Date().getTime(), а затем сортируете их по временной метке. Нулевые значения будут текущим временем, следовательно, большее число и будут отсортированы соответствующим образом. Самый простой способ и к тому же прилично чистый.

kissu 30.05.2024 19:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
66
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вы хотите сравнить даты, вы можете преобразовать их в временные метки эпох, то есть время, прошедшее с 1 января 1970 года по всемирному координированному времени.

new Date().getTime()                               // 1717088172916, now's time
new Date("Thu, 2 January 1970 00:00:00").getTime() // 82800000

Чем меньше число, тем оно старше. Думаю, самый простой способ их сортировки.

Вот достойная статья на эту тему.


В противном случае Temporal API, вероятно, имеет некоторые функции для этого варианта использования. Или использование любой библиотеки дат тоже должно иметь такую ​​​​функцию, но использовать ванильное решение JS всегда приятно.


Чтобы отфильтровать массив для преобразования в текущее время, если null, затем правильно отсортируйте каждую временную метку.

[42, "Thu, 2 January 1970 00:00:00", null, "Thu Jan 10 2023 19:23:55 GMT+0200 (Central European Summer Time)"].map(date => {
  if (!date) { // if null
    return date = new Date().getTime() // set it to the current time
  }
  return new Date(date).getTime() // otherwise, convert the regular Date format into a timestamp
}).sort((a, b) => a - b)
// [42, 82800000, 1673371435000, 1717090069492]

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

Qiuzman 30.05.2024 19:13

@Qiuzman, теперь это более явно?

kissu 30.05.2024 19:29

Я не смог бы перехватить массив элементов в таблице v-данных, чтобы повторно отфильтровать его для выполнения пользовательской функции сортировки в заголовках. Так что этот подход, к сожалению, не сработает. Однако ответ Клода работает. Однако, если вы ответите, вы могли бы выполнить сравнение, чтобы проверить наличие нуля в пользовательской функции сортировки, именно этого я и пытался достичь.

Qiuzman 30.05.2024 19:56

@Qiuzman не уверен, что полностью понимает пользовательскую сортировку или проблему здесь. В конце концов можно было бы сделать сортировку по трем частям. Но поскольку ответ Клода работает, я думаю, используйте его.

kissu 30.05.2024 19:59

да, я прошу прощения, если моя реализация не имеет смысла. По сути, заголовок v-data-table имеет возможность использовать пользовательскую функцию сортировки, и он будет применять ее к массиву данных элементов. Так что на самом деле я не могу ничего отобразить в заголовке, поэтому этот подход не сработает. Тем не менее, подход getTime() — это чистый подход к сравнению, не связанный с DayJS, который мне нравится. Я просто пытался использовать этот подход и учитывать нули. Имеет ли это смысл?

Qiuzman 30.05.2024 20:09
Ответ принят как подходящий

Это может быть проблема с работой функции сравнения. Кажется, что вы также пытаетесь сортировать даты в порядке убывания по умолчанию, что может быть немного запутанным для включения в код.

возьмем, к примеру

(today: dayjs, yesterday: dayjs) => {
  return today.diff(yesterday)
}

today.diff(yesterday) вернет положительное целое число, которое сортирует today после yesterday (yesterday находится сверху)

Чтобы решить эту проблему, я думаю, вам следует попробовать изменить порядок .diff():

function(a: string, b: string) {
    let today = dayjs()
    console.info(c)

    if (a == null && b == null) 
    {
      return 0
    }
    else if (a == null) {
      // "a" is null, so we should return
      // a negative value by diffing a past date with a future day
      return (dayjs(b).diff(today))
    } else if (b == null) 
    {
      // the reverse of above, return a positive value
      return (today.diff(dayjs(a)))
    }
    // lastly, reverse this as well
    return dayjs(b).diff(dayjs(a))
}

Другие вопросы по теме