Группировка полученных сообщений по датам с указанием названия комнаты

Для группировки нескольких сообщений за день нужен массив в значении Record, иначе сообщения перезапишут друг друга. Комнаты индексируйте по id, а часовой пояс дня задайте явно.

Короткий ответ

Что ответить на собеседовании

Для группировки нескольких сообщений за день нужен массив в значении Record, иначе сообщения перезапишут друг друга. Комнаты индексируйте по id, а часовой пояс дня задайте явно.

Подробный разбор

Ответ с пояснениями

Условие

В системе доступны два эндпоинта: один возвращает массив комнат, второй — массив сообщений. Необходимо выполнить запросы к обоим ресурсам, добавить каждому сообщению название соответствующей комнаты и собрать сообщения в структуру, где ключом будет строковое представление даты начала дня в ISO‑формате, а значением — объект сообщения без поля roomId, но с полем roomName. Ниже приведены типы данных и пример ожидаемого результата.

 interface IRoom {
  id: number;
  name: string;
  type: string;
}

interface IMessage {
  roomId: IRoom['id'];
  id: number;
  text: string;
  ts: Date;
}

// // Эндпоинт GET '/rooms' возвращает IRoom[]
// // Эндпоинт GET '/messages' возвращает IMessage[]
// // Необходимо запросить сообщения и комнаты и сгруппировать сообщения по дням

type ProcessedMessage = Omit<IMessage, 'roomId'> & {
  roomName: IRoom['name'];
};

type ProcessedData = Record<string, ProcessedMessage>;

// // при этом строковый ключ – ISO представление даты начала дня ('2022-06-23T00:00:00')

// // Пример результата:
//
// '2023-03-23T00:00:00': { // ISO представление даты начала дня
//   "roomName": "Room name", // название комнаты из rooms
//   "id": 1,
//   "text": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
//   "ts": Thu Mar 23 2023 12:15:15 GMT+0200 (Восточная Европа, стандартное время)
// }
// ...

Ответ

Для группировки нескольких сообщений за день нужен массив в значении Record, иначе сообщения перезапишут друг друга. Комнаты индексируйте по id, а часовой пояс дня задайте явно.

async function groupedMessages() {
  const load = async url => {
    const response = await fetch(url);
    if (!response.ok) throw new Error('Ошибка HTTP');
    return response.json();
  };
  const [rooms, messages] = await Promise.all([load('/rooms'), load('/messages')]);
  const names = new Map(rooms.map(room => [room.id, room.name]));
  const result = Object.create(null);
  for (const { roomId, ts, ...message } of messages) {
    if (!names.has(roomId)) throw new Error('Неизвестная комната');
    const date = new Date(ts);
    if (Number.isNaN(date.getTime())) throw new Error('Неверная дата');
    const day = date.toISOString().slice(0, 10) + 'T00:00:00.000Z';
    (result[day] ??= []).push({ ...message, ts: date, roomName: names.get(roomId) });
  }
  return result;
}

Выбран UTC-день; тип результата — Record<string, ProcessedMessage[]>. По JSON Date приходит строкой, поэтому ts преобразуется явно. Если нужен местный день, нельзя брать UTC-срез; необходимо задать нужную зону. Ключ из условия без Z сам по себе эту зону не определяет.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее