Создание древовидной иерархии из массива объектов

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

const arr = [
  {
    leafName: 'name1',
    nodes: [1,2,3,4]
  },
  {
    leafName: 'name2',
    nodes: [1,2,3,4]
  },
  {
    leafName: 'name3',
    nodes: [1,2,4,5]
  },
  {
    leafName: 'name4',
    nodes: [6]
  }
];

и вот что я ожидаю получить:

const expectedTree = {
  name: 'some root name',
  children: [
    {
      name: 1,
      children: [
        {
          name: 2,
          children: [
            {
              name: 3,
              children: [
                {
                  name: 4,
                  children: [
                    {
                      name: 'name1'
                    },
                    {
                      name: 'name2'
                    }
                  ]
                }
              ]
            },
            {
              name: 4,
              children: [
                {
                  name: 5,
                  children: [
                    {
                      name: 'name3'
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    {
      name: 6,
      children: [
        {
          name: 'name4'
        }
      ]
    }
  ]
};

как видите, leafName должен быть последним узлом в ветке дерева. Также, если есть частичное совпадение от корневого узла к какому-либо другому узлу, новый дочерний элемент должен быть добавлен из узла, который соответствует последнему. Например, давайте возьмем совпадение первых двух членов arr[1].nodes и arr[2].nodes, это означает, что они должны быть в одной ветке, только 4 и 5 из arr[2].nodes, разделенных на отдельную ветку (как дочерние элементы для { name: 2, children: [should go here] }). Я очень надеюсь, что вы уловили идею, и я также надеюсь, что кто-то мне в этом поможет. Потому что я застрял в этом уже два дня и сам не мог придумать «чистое» решение для этого.

Будем очень признательны за любые комментарии. ;)

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете зациклить массив и узлы и уменьшить узлы, глядя на одно и то же имя для каждого уровня. Если узел не существует, создайте новый и верните дочерние элементы узла.

var array = [{ leafName: 'name1', nodes: [1, 2, 3, 4] }, { leafName: 'name2', nodes: [1, 2, 3, 4] }, { leafName: 'name3', nodes: [1, 2, 4, 5] }, { leafName: 'name4', nodes: [6] }],
    result = [];

array.forEach(({ leafName, nodes }) => {
    nodes
        .reduce((level, name) => {
            var temp = level.find(o => o.name === name);
            if (!temp) {
                level.push(temp = { name });
            }
            return temp.children = temp.children || [];
        }, result)
        .push({ name: leafName });
});

console.info(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Другие вопросы по теме