Задать вопрос

Как организовать дерево категорий из json ответа с полями nested sets?

Добрый день! Делаю импорт категории товаров из апи поставщика. При запросе категории товаров получаю json полный вывод можно посмотреть тут https://api.al-style.kz/api/categories

Хочу получить меню такого вида
62162c90b9493307646283.jpeg

На скрине заполненно тестовыми данными 2мя циклами шаблонные поля апендятся в родителя

Сначала планировал проходится по ответу подразумевая что категории идут одна за одной и проверкой находжени правого значения в диапазоне значений предыдущего элемента строить подменю. Позже заметил что есть провал то есть идут в ряд до 9 после левое значение сразу 12. Как при дальнейшем находжени 12-13 вклинить его в первую категорию не придумал. На ум пришло только строить как есть и постоянно проверять дерево категорий при получении новой. То есть получили первую 1-20 добавили, получили вторую 2-3 проверили дерево нашли куда помещается с апендили и так далее. Но чувствую что это не то.

Подскажите пожалуйста как можно эффективнее пройтись по ответу и собрать дерево категорий как на скрине
  • Вопрос задан
  • 264 просмотра
Подписаться 1 Средний 1 комментарий
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
Собираете из плоского массива дерево:

const createTreeFromNestedSets = arr => [...arr]
  .sort((a, b) => a.left - b.left)
  .reduce((acc, n) => {
    while (acc.at(-1).at(-1).right < n.left) {
      acc.pop();
    }

    if (acc.at(-1).at(-1).right > n.left) {
      acc.push(acc.at(-1).at(-1).children);
    }

    acc.at(-1).push({ ...n, children: [] });

    return acc;
  }, [ [ { left: -Infinity, right: Infinity, children: [] } ] ])
  [0][0].children;

Затем из дерева собираете разметку:

const createTreeHTML = (arr, nodeTemplate) =>
  Array.isArray(arr) && arr.length
    ? `<ul>${arr.map(n => `
         <li>
           ${nodeTemplate(n)}
           ${createTreeHTML(n.children, nodeTemplate)}
         </li>`).join('')}
       </ul>`
    : '';

Которую вставляете куда там вам надо:

containerElement.insertAdjacentHTML('beforeend', createTreeHTML(
  createTreeFromNestedSets(data),
  item => `<input data-id="${item.id}" type="checkbox">${item.name}`
));
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы