Вы можете использовать объект в качестве вспомогательной структуры для несортированных данных и построить дерево.
Для получения плоского массива вы можете выполнить итерацию дерева и объединить плоские дочерние элементы с рекурсивной функцией.
function getTree(array) {
var o = {};
array.forEach(({ id, path }) => {
var parents = path.split('.'),
parent = parents[parents.length - 2];
Object.assign(o[id] = o[id] || {}, { id, path });
o[parent] = o[parent] || {};
o[parent].children = o[parent].children || [];
o[parent].children.push(o[id]);
});
return o.undefined.children;
}
function getFlat(array = []) {
return array.reduce((r, { id, path, children }) =>
r.concat({ id, path }, getFlat(children)), []);
}
var input = [{ path: '1', id: '1' }, { path: '2', id: '2' }, { path: '3', id: '3' }, { path: '3.4', id: '4' }, { path: '3.5', id: '5' }, { path: '3.4.6', id: '6' }, { path: '3.4.7', id: '7' }, { path: '8', id: '8' }],
tree = getTree(input),
flat = getFlat(tree);
console.log(tree);
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Решение без сохранения path
.
function getTree(array) {
var o = {};
array.forEach(({ id, path }) => {
var parents = path.split('.'),
parent = parents[parents.length - 2];
Object.assign(o[id] = o[id] || {}, { id });
o[parent] = o[parent] || {};
o[parent].children = o[parent].children || [];
o[parent].children.push(o[id]);
});
return o.undefined.children;
}
function getFlat(array = [], path = []) {
return array.reduce((r, { id, children }) => {
var p = path.concat(id);
return r.concat({ id, path: p.join('.') }, getFlat(children, p));
}, []);
}
var input = [{ path: '1', id: '1' }, { path: '2', id: '2' }, { path: '3', id: '3' }, { path: '3.4', id: '4' }, { path: '3.5', id: '5' }, { path: '3.4.6', id: '6' }, { path: '3.4.7', id: '7' }, { path: '8', id: '8' }],
tree = getTree(input),
flat = getFlat(tree);
console.log(tree);
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }