@Psihoshit

Как при построении дерева на основе массива объекта пометить дочерние элементы?

Есть массив:

const data = [
  {
    id: 1122031,
    title: "Banner",
    children: [
      {
        id: 1122032,
        title: "prod 1"
      },
      {
        id: 1122033,
        title: "prod 2"
      },
      {
        id: 1122034,
        title: "prod 3"
      },
      {
        id: 1366085,
        title: "prod 6",
        children: [
          {
            id: 1362085,
            title: "prod 16"
          }
        ]
      }
    ]
  }
];

И есть функция:

function createTree(data, defaultId) {
  const ul = document.createElement("ul");

  data.map((item, index) => {
    const li = document.createElement("li");
    li.textContent = item.id;

    if (item.children) {
      li.appendChild(createTree(item.children, index));
    }

    ul.appendChild(li);
  });

  return ul;
}

Надо сделать так, чтобы в список выводился следующим образом:

<ul>
      <li>
        children
        <ul>
          <li>
            0_children
            <ul>
              <li>0_children_0</li>
              <li>0_children_1</li>
              <li>0_children_2</li>
              <li>
                0_children_3
                <ul>
                  <li>
                    0_children_3_children_0
                  </li>
                  <li>
                    0_children_3_children_1
                  </li>
                </ul>
              </li>
            </ul>
          </li>
          <li>
            1_children
          </li>
        </ul>
      </li>
    </ul>

Важно, чтобы к каждому дочернему элементу добавлялся индекс предыдущего и добавлялся текущий индекс.

Как это сделать?
  • Вопрос задан
  • 111 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
Пусть второй параметр будет массивом индексов, по умолчанию - пустой (соответственно, когда вызываете функцию сами, его передавать не надо). В начале обработки элемента данных кладёте его индекс в массив, после обработки убираете. Ну а текст - собираете из массива какой вам нужен:

const createTreeElement = (data, index = []) =>
  Array.isArray(data) && data.length
    ? data.reduce((ul, n, i) => (
        index.push(i),
        ul.append(document.createElement('li')),
        ul.lastChild.append(index.join('_'), createTreeElement(n.children, index)),
        index.pop(),
        ul
      ), document.createElement('ul'))
    : '';


document.body.append(createTreeElement(data));

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

const createTreeHTML = (data, index = '') =>
  data instanceof Array && data.length
    ? `<ul>${data.map((n, i) => `
         <li>
           ${(i = index + (index && '_') + i)}
           ${createTreeHTML(n.children, i)}
         </li>`).join('')}
       </ul>`
    : '';


document.body.insertAdjacentHTML('beforeend', createTreeHTML(data));
Ответ написан
Комментировать
@dimoff66
Кратко о себе: Я есть
function createTree(data, defaultId, parentIds = '') {
  const ul = document.createElement("ul");

  data.map((item, index) => {
    const li = document.createElement("li");
    const id = [parentIds, item.id].join('_')
    li.textContent = id;

    if (item.children) {
      li.appendChild(createTree(item.children, index, id));
    }

    ul.appendChild(li);
  });

  return ul;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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