Преобразовать массив в нужную структуру Объектов

Ребят, помогите решить одну задачку, не ладиться у меня с массивами. Суть такая, у меня на входе есть массив массивов.

items: [
        [ 'группа', 'цена', 'описание', 'порция', 'блюдо' ],
        [ 'кофе', '100', 'кофе с молоком', '300', 'капучино' ],
        [ '', '200', 'Кофе с молоком', '300', 'Латте' ],
        [ 'Колла', '60', 'оригинальная', '500', 'колла' ],
        [ '', '100', 'zero', '500', 'колла' ],
        [ 'Вино', '600', 'белое вино', '250', 'Шато Бло бло' ],
        [ '', '500', 'красное вино', '250', 'Шато Тро ло ло' ],
      ]

Изначально, я пытался решить проблему отсутствия данных в массиве в колонке группа (такое может быть) Пример массива Решил я это следующим способом. создал вот такое computed свойство:

createMenu () {
      let value = ''

      return this.items.slice(1).map((item) => {
        let newItem = item[0]
        if (newItem) {
          value = newItem
        } else {
          newItem = value
        }
        return newItem
      })
    }

Все прекрасно, но нужно как-то из этого массива сделать нужную структуру, Объектов. А я ни как не могу к этому подступиться. Структура должна выглядеть примерно так:

Пример структуры

ну и присутствовать соответствующая логика. Если я бегу циклом по группе, и если значение новое, я создаю новый item, в него закидываю блюда и тд. А если оно такое же, то я не создаю новый item а просто закидываю туда блюда. Я что-то пока не могу понять, с чего начать(

Буду благодарен любой наводке))


Ответы (1 шт):

Автор решения: Максим Вишневский

Если я правильно понял ваш вопрос, то должно быть что-то примерно такое:

// заполняем пустые груп неймы и возвращаем обновленные массивы
const fillEmptyGroupNames = (items) => {
  let previousGroupName = 'Кофе';

  return items.map((item) => {
    const [groupName, ...otherFields] = item;

    if (groupName) {
      previousGroupName = groupName;
      return item;
    }

    return [previousGroupName, ...otherFields];
  });
};

// конвертируем в нужную вам структуру
const convertToStructuredMenu = (items) => {
  // конфиг, в котором ключ - название группы,
  // значение - индекс в результирующем массиве
  const alreadyUsedGroups = {};

  return items.reduce((
    acc,
    [
      groupName,
      name,
      description,
      price,
      measure,
    ],
  ) => {
    const item = {
      name,
      description,
      prices: {
        price,
        measure,
      },
    };

    if (!Object.prototype.hasOwnProperty.call(alreadyUsedGroups, groupName)) {
      acc.push({ name: groupName, items: [item] });
      alreadyUsedGroups[groupName] = acc.length - 1;

      return acc;
    }

    acc[alreadyUsedGroups[groupName]].items.push(item);

    return acc;
  }, [])
};

export default {
  data: () => ({
    items: [
      [ 'группа', 'цена', 'описание', 'порция', 'блюдо' ],
      [ 'Кофе', '100', 'кофе с молоком', '300', 'капучино' ],
      [ '', '200', 'Кофе с молоком', '300', 'Латте' ],
      [ 'Колла', '60', 'оригинальная', '500', 'колла' ],
      [ '', '100', 'zero', '500', 'колла' ],
      [ 'Вино', '600', 'белое вино', '250', 'Шато Бло бло' ],
      [ '', '500', 'красное вино', '250', 'Шато Тро ло ло' ],
    ],
  }),
  computed: {
    menu() {
      const [, ...items] = this.items; // извлекаем всё, кроме хедеров
      return fillEmptyGroupNames(items);
    },
    structuredMenu() {
      return convertToStructuredMenu(this.menu);
    },
  },
};

→ Ссылка