将字符串拆分为树状结构的最有效方法



我有一个字符串的动态数组。每个字符串表示树的节点。如果任何字符串具有"0"_&";,我想拆分成每个节点,并将其存储在另一个数组中。

对于。例如。"0_2_0_0"需要拆分为"0";0"0_ 2"0_2_0""0_2_0";然后将其存储在新阵列中。我通过使用multiple for循环实现了这一点。我不认为这是最有效的方法

let visibleTreeNodes = [];
const treeData = ['0_0', '0_1', '0_2_0_0', '1'];
for (let i = 0; i < treeData.length; i++) {
if (treeData[i].includes('_')) {
const nodesArray = treeData[i].split('_');
for (let i = 0; i < nodesArray.length; i++) {
let node = nodesArray[0];
for (let j = 0; j <= i; j++) {
if (j !== 0) {
node = node + '_' + nodesArray[j];
}
}
if (visibleTreeNodes.indexOf(node) === -1) {
visibleTreeNodes.push(node)
}
}
} else if (visibleTreeNodes.indexOf(treeData[i]) === -1) {
visibleTreeNodes.push(treeData[i])
}
}
console.log(treeData);
console.log(visibleTreeNodes);

留给我的只是解释(并记住(@Nina Scholz构建树的部分。我将基本上重命名变量并使用熟悉的语法。

// data can be directories lists
const data = ['0_0', '0_1', '0_2_0_0', '1']
// the classic group by using reduce
var result = data.reduce(function(agg, item) {
// buliding tree path incrementally
var pointer = agg;
item.split('_').forEach(function(part) {
pointer[part] = pointer[part] || {}
pointer = pointer[part];
});
return agg;
}, {});
// result is classic object tree 
console.log(result);
// iterate to print desired output:
function iterate(tree, parent) {
Object.keys(tree).forEach(function(key) {
var value = tree[key];
var full = (parent ? parent + "_"  : '') + key
console.log(full)
if (typeof value === 'object') {
iterate(value, full)
}
})
}
iterate(result)
.as-console-wrapper {max-height: 100% !important}

您可以先构建一个树,然后从键中获取路径。

const
getFlat = object => Object.keys(object).flatMap(k => [
k,
...getFlat(object[k]).map(p => `${k}_${p}`)
]),
data = ['0_0', '0_1', '0_2_0_0', '1'],
result = getFlat(data.reduce((t, s) => {
s.split('_').reduce((o, k) => o[k] ??= {}, t);
return t;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

我试着简化你的方程式。我看到了下面的片段。对于每个输入字符串,它在forEach内部有一个forEach和一个while循环。

let visibleTreeNodes = [];
const treeData = ['0_0', '0_1', '0_2_0_0', '1'];
treeData.forEach(x => {
const arr = x.split("_");
let i = 0;
let node = arr[0];
while (i < arr.length) {
if (!visibleTreeNodes.includes(node)) {
visibleTreeNodes.push(node);
}
node = [node, arr[i + 1]].join("_");
i++;
}
});
console.log(treeData);
console.log(visibleTreeNodes);

你可以自由地想出更好的解决方案。

感谢

A"一个衬垫":

const treeData = ['0_0', '0_1', '0_2_0_0', '1'];
const visibleTreeNodes = [...new Set(treeData.flatMap(
s=>s.split('_').reduce((a, si, i)=> [...a, a[i-1]+'_'+si])
))];// Set used to remove duplicates
console.log(visibleTreeNodes)
尽管效率必须经过测试-更简洁的解决方案不会自动缩短的运行时间

最新更新