Код немного длинный, но, на мой взгляд, довольно простой для понимания.Он чрезвычайно надежен - не требует сортировки массива и не требует существования 01
для обработки 0102
(в случае необходимости).Код может быть намного короче без обработки этих случаев, но я подумал, что вам это может понадобиться.
Во-первых, создайте объектную древовидную структуру данных из данных.Это дерево имеет ключи и значения и очень эффективно для построения, потому что доступ по индексу - O (1).Затем преобразуйте объектное дерево в окончательную структуру данных на основе массива, обойдя объектное дерево и затем преобразовав каждый слой в массивы.
Я также активно использую рекурсию, поскольку рекурсия хорошо подходитдля создания и обхода деревьев.
По сравнению с другими ответами мой алгоритм имеет большую временную сложность, потому что я создаю словарь / объект, который имеет O (1) доступ при создании дерева.Другие алгоритмы выполняют поиск в каждом слое, что неэффективно.Мой алгоритм работает в O (N), тогда как другие ответы здесь короче, но в O (N ^ 2).
Просто скопируйте функцию format
в ваш код, и она должна быть полезной.
const codes = [
{ code: '01' },
{ code: '0101' },
{ code: '0102' },
{ code: '010201' },
{ code: '0103' },
{ code: '02' },
{ code: '0201' },
{ code: '0202' },
];
function format(codes) {
// Splits the string into an array of 2-character strings.
const SPLIT_REGEX = /.{2}(?=(.{2})+(?!.))|.{2}$/g;
const codeFragments = codes.map(obj => obj.code.match(SPLIT_REGEX));
// 1. Represent the data as a tree which is more efficient to build.
const tree = {};
function createTree(tree, fragments) {
let node = tree;
fragments.forEach(fragment => {
if (!node[fragment]) {
node[fragment] = {};
}
node = node[fragment];
});
}
codeFragments.forEach(fragments => createTree(tree, fragments));
/* tree will have the structure:
{
"01": {
"01": {},
"02": {
"01": {}
},
"03": {}
},
"02": {
"01": {},
"02": {}
}
}
*/
// 2. Convert the tree structure into the desired format.
function generateCodesFromTree(tree, previous) {
const nestedCodes = [];
Object.keys(tree).forEach(treeNode => {
const code = previous + treeNode;
const children = generateCodesFromTree(tree[treeNode], code);
const nestedCode = { code };
if (children.length > 0) {
nestedCode.children = children;
}
nestedCodes.push(nestedCode);
});
return nestedCodes;
}
return generateCodesFromTree(tree, '');
}
console.log(format(codes));