F
F
frolovsky2020-12-06 11:26:21
JavaScript
frolovsky, 2020-12-06 11:26:21

How to create a recursive function to parse an array?

I'm trying to write a recursive function that could cast an object received from the server to the desired form:

What do I want to bring
{
        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' }
                ]
              }
            ]
          },

What I get from the server:
What I get from the server
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;


What I have written so far only outputs 2 levels of nesting (code below). I understand that it is necessary to do recursion here, I have been trying to solve this problem for 2 days, but the pancake does not work at all. Tell me in which direction to at least look, is it possible?
I just don't understand, so I pass to the recursive function:
1) An object of type { id, name } (hereinafter Object).
2) Check if { id } has children.
2.1 If not, I return the passed object.
2.2 If there is, I run through folders_h (hierarchy) and look for an element with { id } there and take the childeren array from there (includes id). Next I create Object['children'] = [];
And in the loop I go through each child, add information about it to the Object['children].push( {id, name} ) array.

Further, I don’t understand at all how I can add another children array for the nested element.

My code
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));
});

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Somewhere Intech, 2020-12-06
@frolovsky

// чтобы меньше бегать в циклах
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))

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question