Плоский массив в массив вложенных объектов - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь взять плоский массив путей и создать вложенный массив объектов.У меня проблема с рекурсивной частью генерации дочерних узлов ...

Начальный массив:

const paths = [ 
  '/',
  '/blog',
  '/blog/filename',
  '/blog/slug',
  '/blog/title',
  '/website',
  '/website/deploy',
  '/website/infrastructure',
  '/website/infrastructure/aws-notes',
];

С желаемой структурой вывода:

[
  { 
    path: '/',
  },
  {
    path: '/blog',
    children: [
      {
        path: '/blog/filename',
      },
      {
        path: '/blog/slug',
      },
      {
        path: '/blog/title',
      }
    ]
  },
  { 
    path: '/website',
    children: [
      {
        path: '/website/deploy',
      },
      {
        path: '/website/infrastructure',
        children: [
          {
            path: '/website/infrastructure/aws-notes',
          }
        ],
      },
    ],
  },
]

Вот где я сейчас нахожусь, я пробовал несколько вещей, но в конечном итоге заканчивается бесконечными циклами или плохой структурой:

const getPathParts = (path) => path.substring(1).split('/');
const getPathLevel = (path) => getPathParts(path).length - 1;
const getTree = (paths) => paths.reduce((tree, path, i, paths) => {
  const pathParts = getPathParts(path);
  const pathDepth = getPathLevel(path);
  const current = pathParts[pathDepth];
  const parent = pathParts[pathDepth - 1] || null;
  const item = {
    path,
    children: [],
  };

  if (pathDepth > 0 || parent !== null) {
    // recursive check for parent, push this as a child to that parent?
    return [...tree];
  }

  return  [
    ...tree, 
    item,
  ];
}, []);

Я пытался array.find|some|filter, чтобы получить родителя, но яЯ в растерянности, как подтолкнуть узел как ребенка в правильный вложенный узел.ПРИМЕЧАНИЕ: я извлек код для примера, извините за любые проблемы синтаксиса / орфографии.

1 Ответ

0 голосов
/ 30 ноября 2018

Вы можете использовать вложенный подход, взяв пути и разделив их и проверив, существует ли объект с путем уже или нет.Если нет, нажмите новый объект.

Позже верните дочерние элементы фактического объекта.Продолжайте до тех пор, пока не будет доступно больше элементов пути.

const
    paths = ['/', '/blog', '/blog/filename', '/blog/slug', '/blog/title', '/website', '/website/deploy', '/website/infrastructure', '/website/infrastructure/aws-notes'],
    result = paths.reduce((r, path) => {
        path.split(/(?=\/)/).reduce((a, _, i, p) => {
            var temp = a.find(o => o.path === p.slice(0, i + 1).join(''));
            if (!temp) {
                a.push(temp = { path, children: [] });
            }
            return temp.children;
        }, r);
        return r;
    }, []);

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

Для создания с использованием только путей к конечным каталогам можно использовать части пути для создания.

Этот подход предотвращает использование пустых дочерних массивов..

const
    paths = [
        '/',
        '/blog/filename',
        '/blog/slug',
        '/blog/title',
        '/website/deploy',
        '/website/infrastructure/aws-notes'
    ],
    result = [];

paths.reduce((r, string) => {
    string.split(/(?=\/)/).reduce((o, _, i, p) => {
        o.children = o.children || [];
        var path = p.slice(0, i + 1).join(''),
            temp = o.children.find(o => o.path === path);
        if (!temp) {
            o.children.push(temp = { path });
        }
        return temp;
    }, r);
    return r;
}, { children: result });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...