@frolovsky

Как создать рекурсивную функцию для парсинга массива?

Я пытаюсь написать рекурсивную функцию, которая могла бы приводить получаемый с сервера объект к нужному виду:

К чему хочу привести
{
        id: 1,
        name: 'string',
        children: [
          { id: 2, name: 'string' },
          { id: 3, name: 'string' },
          { id: 4, name: 'string' }
        ]
      },
      {
        id: 5,
        name: 'string:',
        children: [
          {
            id: 6,
            name: 'string',
            children: [
              {
                id: 7,
                name: 'string',
                children: [
                  { id: 8, name: 'string' },
                  { id: 9, name: 'string' }
                ]
              }
            ]
          },

То, что я получаю с сервера:
То что получаю с сервера
const folders = [
  {
    id: 1000,
    pid: [
      0,
    ],
    index: [
      {
        0: 1,
      },
    ],
    name: 'Раздел (папка) 1000 - Уровень 1',
    have_children: true,
  },
  {
    id: 1100,
    pid: [
      0,
    ],
    index: [
      {
        0: 1,
      },
    ],
    name: 'Раздел (папка) 1100 - Уровень 1',
    have_children: true,
  },
  {
    id: 1200,
    pid: [
      0,
    ],
    index: [
      {
        0: 1,
      },
    ],
    name: 'Раздел (папка) 1200 - Уровень 1',
    have_children: true,
  },
  {
    id: 1001,
    pid: [
      1000,
    ],
    index: [
      {
        1000: 1,
      },
    ],
    name: 'Раздел (папка) 1001 - Уровень 2',
    have_children: false,
  },
  {
    id: 1002,
    pid: [
      1000,
    ],
    index: [
      {
        1000: 1,
      },
    ],
    name: 'Раздел (папка) 1002 - Уровень 2',
    have_children: false,
 
  },
  {
    id: 1101,
    pid: [
      1100,
    ],
    index: [
      {
        1100: 1,
      },
    ],
    name: 'Раздел (папка) 1101 - Уровень 2',
    have_children: false,
  },
];
const folders_h = [
  {
    id: 0,
    children: [
      1000,
      1100,
      1200,
    ],
  },
  {
    id: 1000,
    children: [
      1001,
      1002,
    ],
  },
  {
    id: 1100,
    children: [
      1101,
    ],
  },
];
const folders_root_id = 0;


То, что я написал на данный момент выводит только 2 уровня вложенности (код ниже). Я понимаю что тут надо сделать рекурсию, уже 2 дня пытаюсь решить эту задачу, но блин вообще никак не выходит. Подскажите в какую сторону хотя бы смотреть, возможно ли это?
Я просто не понимаю, вот я передаю в рекурсивную функцию:
1) Объект типа { id, name } (далее Object).
2) Проверю есть ли у { id } дети.
2.1 Если нет, возвращаю передаваемый объект.
2.2 Если есть, пробегаюсь по folders_h (иерархии) и ищу там элемент с { id } и беру от туда массив childeren (включает в себя id). Далее создаю Object['children'] = [];
И в цикле по каждому чилдрену прохожусь, добавляю о нем информацию в массив Object['children].push( {id, name} ).

Дальше я вообще не понимаю как мне для вложенного элемента добавить ещё один массив children.

Мой код
const rootFolders = folders_h.find(f => f.id === folders_root_id).children;
const folderStructure = [];

const getFullFolder = (o, lastId) => {
  if (!lastId) {
    lastId = o.id;
  }
  if (folders_h.find(f => f.id === lastId)) {
    o['children'] = [];
    folders_h.find(f => f.id === lastId).children.forEach(ch => {
      o['children'].push({
        id: ch,
        name: getFolderName(ch)
      })
    })
  } 
  return o;
}

function getFolderName(id) {
  return folders.find(f => f.id === id).name;
}

rootFolders.forEach(rootFolderId => {
  const item = folders.find(folder => folder.id === rootFolderId);
  const baseFolder = {
    id: item.id,
    name: item.name
  };

  folderStructure.push(getFullFolder(baseFolder));
});
  • Вопрос задан
  • 119 просмотров
Решения вопроса 1
john36allTa
@john36allTa
alien glow of a dirty mind
// чтобы меньше бегать в циклах
let foldersMap = new Map();

for (let folder of folders_h)
	foldersMap.set(folder.id, { children: folder.children })

for (let folder of folders){
	let item = foldersMap.get(folder.id)
	if (item) item.name = folder.name
	else foldersMap.set(folder.id, { name: folder.name });
}

function helper(id){ 
	let folder = foldersMap.get(id);
	return !folder.children ? { id, name: folder.name } : { id, name: folder.name, children: folder.children.map( child => helper(child) ) }
}

let collection = folders_h.find( folder => folder.id === folders_root_id).children.map(child => helper(child))
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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