Как сопоставить числовые дни с названиями дней на локализованном языке с помощью intl в React?

Вопрос или проблема

Я работаю над проектом на React, где мне нужно сопоставить числовые значения дней (например, 0 для воскресенья, 1 для понедельника и т.д.) с их соответствующими названиями на днях (как на английском, так и на французском), в зависимости от локали пользователя. Я использую intl.formatMessage для локализации и имею вспомогательную функцию для получения переведенных названий дней.

Вот моя функция retrieveWeekDays:

export const retrieveWeekDays = intl => {
  return [
    { key: 'selectAll', label: intl.formatMessage({ ...translations.days.allDays }), value: 'Все' },
    { key: 0, label: intl.formatMessage({ ...translations.days.sunday }), value: 'Воскресенье' },
    { key: 1, label: intl.formatMessage({ ...translations.days.monday }), value: 'Понедельник' },
    { key: 2, label: intl.formatMessage({ ...translations.days.tuesday }), value: 'Вторник' },
    { key: 3, label: intl.formatMessage({ ...translations.days.wednesday }), value: 'Среда' },
    { key: 4, label: intl.formatMessage({ ...translations.days.thursday }), value: 'Четверг' },
    { key: 5, label: intl.formatMessage({ ...translations.days.friday }), value: 'Пятница' },
    { key: 6, label: intl.formatMessage({ ...translations.days.saturday }), value: 'Суббота' },
  ];
};

Вот мой текущий рабочий код для сопоставления дней:

case 5: 
  const mappedDayNames = parsedData.permittedDays
    .map(day => {
      const matchingDay = weekDaysArray.find(dayObj => dayObj.key === day);
      return matchingDay ? matchingDay.label : ''; // Безопасный доступ к `label`
    })
    .filter(Boolean); // Удалить любые пустые строки в случае, если день не был найден

  // Соедините названия дней с запятой
  const formattedDayList = mappedDayNames.join(', ');

  resultMessage = intl.formatMessage(
    { ...translations.rules.applicableOnSpecificDays },
    { permittedDays: formattedDayList }
  );
  break;

В этом случае weekDaysArray извлекается с помощью функции retrieveWeekDays(intl), которая возвращает массив объектов, содержащих ключ (числовой день) и метку (переведенное название дня) для соответствующей локали.

Условие задачи:

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

Ответ или решение

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

  1. Оптимизация функции retrieveWeekDays:
    Вместо повторного вызова intl.formatMessage для каждого дня недели, мы можем создать отдельную функцию для получения переводов и использовать массив с предопределёнными днями.
const daysOfWeek = [
  { key: 0, defaultLabel: 'Sunday' },
  { key: 1, defaultLabel: 'Monday' },
  { key: 2, defaultLabel: 'Tuesday' },
  { key: 3, defaultLabel: 'Wednesday' },
  { key: 4, defaultLabel: 'Thursday' },
  { key: 5, defaultLabel: 'Friday' },
  { key: 6, defaultLabel: 'Saturday' },
];

export const retrieveWeekDays = (intl) => {
  const translatedDays = daysOfWeek.map(day => ({
    key: day.key,
    label: intl.formatMessage({ ...translations.days[day.defaultLabel.toLowerCase()] }),
    value: day.defaultLabel,
  }));

  return [
    { key: 'selectAll', label: intl.formatMessage({ ...translations.days.allDays }), value: 'All' },
    ...translatedDays,
  ];
};
  1. Упрощение маппинга дней:
    Чтобы избежать нескольких вызовов find, мы можем использовать объект для быстрого доступа к дню.
case 5: 
  const weekDaysArray = retrieveWeekDays(intl);
  const dayLookup = Object.fromEntries(weekDaysArray.map(dayObj => [dayObj.key, dayObj.label]));

  const mappedDayNames = parsedData.permittedDays
    .map(day => dayLookup[day])
    .filter(Boolean); // Удаляем пустые строки

  // Объединяем названия дней с запятой
  const formattedDayList = mappedDayNames.join(', ');

  resultMessage = intl.formatMessage(
    { ...translations.rules.applicableOnSpecificDays },
    { permittedDays: formattedDayList }
  );
  break;

Объяснение улучшений:

  • Производительность: Использование Object.fromEntries позволяет создать объект dayLookup, что значительно ускоряет доступ к переводу каждого дня без необходимости перебора массива.
  • Читаемость кода: Оптимизированная структура делает код более понятным и легким для поддержки.
  • Локализация: Все локализированные строки теперь управляются через одну функцию, что упрощает изменение структуры данных и добавление новых языков.

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

Оцените материал
Добавить комментарий

Капча загружается...