Как на javascript сделать древовидную структуру массива из массива из трёх полей id, name, parent?

Подскажите, если я имею массив подобного вида и на сервере хранится в подобной структуре

[
  id:1,name:"Text",parent:0,
  id:2,name: "Folder in Parent Folder with id 1", parent: 1,
  id:555, name: "Rekursive folder in Folder 2....", parent:2
]

Я бы хотел в списке отрисовать эти данные, полученные данные отрисовать из массива, где parent это родительский элемент.

[
 id:1, name:"Text",
 children: [
   id:2,name: "Folder in Parent Folder with id 1", 
   children: [
     id:555, name: "Rekursive folder in Folder 2...."
   ]
]

Как это преобразовать рекурсивно, так как неизвестен уровень вложений?
  • Вопрос задан
  • 897 просмотров
Решения вопроса 2
@dimoff66
Кратко о себе: Я есть
Всего пару строчек кода, которые при желании можно и в одну соединить в ущерб наглядности

const map = Object.assign({} , ...arr.map(v => 
  ({ [v.id]: Object.assign(v, { children: [] }) })
))

const tree = Object.values(map).filter(v => 
 !(v.parent && map[v.parent].children.push(v))
)
Ответ написан
john36allTa
@john36allTa
alien glow of a dirty mind
на скорую руку как то так можно
var rawData = [
  { id:1,name:"Root element",parent:0 },
  { id:2,name: "Child of the first element", parent: 1},
  { id:555, name: "Child of the second element", parent:2}
];


function pack( data ){
	const childs = id => 
		data.filter( item => item.parent === id )
			.map( 
				({id,name}) => ({id,name, children: childs(id)}) 
			).map(
				({id,name,children}) => children.length ? {id,name, children} : { id, name }
			);
	return childs(0);
}

console.log(JSON.stringify(pack(rawData)))
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
WblCHA
@WblCHA
Я так понимаю входные данные ─ это массив объектов с любыми ид?
Тогда можно так:
Создаёшь константу пустого массива, форичем проходишься по входным данным и по паренту пихаешь детей куда надо.
Всё.
Ответ написан
@zealous
пост старый - но интересный
вдруг кому пригодится
вот более быстрое решение чем у Дмитрий. в первом ответе
можно добавить в тесты из первого ответа от Дмитрий - будете приятно удивлены
function test4( list ) {
  var map = {}, node, roots = [], i;

  for (i = 0; i < list.length; i += 1) {
    map[list[i].id] = i; 
    list[i].children = []; 
  }

  for (i = 0; i < list.length; i += 1) {
    node = list[i];
    if (node.parent) {
      list[map[node.parent]].children.push(node);
    } else {
      roots.push(node);
    }
  }
  return roots;
}

вот тут добавлен этот вариант https://jsfiddle.net/zteogkuL/
------------------------
Размер:1000, повторить:100 раз
Somewhere Intech: 563.821044921875 ms
Bavashi: 614.713134765625 ms
Дмитрий: 241.9619140625 ms
--fast--: 3.85009765625 ms
------------------------
Размер:2000, повторить:50 раз
Somewhere Intech: 1106.697021484375 ms
Bavashi: 1223.849853515625 ms
Дмитрий: 154.4228515625 ms
--fast--: 3.881103515625 ms
------------------------
Размер:5000, повторить:20 раз
Somewhere Intech: 2736.092041015625 ms
Bavashi: 3024.505859375 ms
Дмитрий: 120.299072265625 ms
--fast--: 4.150146484375 ms
------------------------
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы