【发布时间】:2022-01-04 17:50:49
【问题描述】:
我正在使用来自 UI 框架的表格组件,它为我生成以下标题
基于此配置
(最终结果)
[
[
{
"title": "Section 1",
"rowspan": "4",
"colspan": "1"
},
{
"title": "Section 2",
"rowspan": "1",
"colspan": "2"
},
{
"title": "Section 3",
"rowspan": "1",
"colspan": "3"
},
{
"title": "Section 4",
"rowspan": "1",
"colspan": "1"
}
],
[
{
"title": "Section 2.1",
"rowspan": "3",
"colspan": "1"
},
{
"title": "Section 2.2",
"rowspan": "3",
"colspan": "1"
},
{
"title": "Section 3.1",
"rowspan": "3",
"colspan": "1"
},
{
"title": "Section 3.2",
"rowspan": "1",
"colspan": "2"
},
{
"title": "Section 4.1",
"rowspan": "1",
"colspan": "1"
}
],
[
{
"title": "Section 3.2.1",
"rowspan": "2",
"colspan": "1"
},
{
"title": "Section 3.2.2",
"rowspan": "2",
"colspan": "1"
},
{
"title": "Section 4.1.1",
"rowspan": "1",
"colspan": "1"
}
],
[
{
"title": "Section 4.1.1.1",
"rowspan": "1",
"colspan": "1"
}
]
]
我想简化配置。应该只有一个树状结构,我想动态计算行和列跨度
(起点)
[
{
"title": "Section 1"
},
{
"title": "Section 2",
"children": [
{
"title": "Section 2.1"
},
{
"title": "Section 2.2"
}
]
},
{
"title": "Section 3",
"children": [
{
"title": "Section 3.1"
},
{
"title": "Section 3.2",
"children": [
{
"title": "Section 3.2.1"
},
{
"title": "Section 3.2.2"
}
]
}
]
},
{
"title": "Section 4",
"children": [
{
"title": "Section 4.1",
"children": [
{
"title": "Section 4.1.1",
"children": [
{
"title": "Section 4.1.1.1"
}
]
}
]
}
]
}
]
我想过如何将起点数组映射到最终结果数组。这些是我的假设:
- 递归遍历数组
- 像这样计算 colspan(宽度)
- 如果没有孩子 =>
1 - 如果有任何孩子 => 下一个深度的所有孩子的 colspan 的总和
- 如果没有孩子 =>
- 计算行跨度(高度)
- 如果没有孩子 => 整个树的最大深度 - 当前深度
- 如果有孩子 =>
1
我目前的做法
const configuredHeaders = [{
title: "Section 1"
},
{
title: "Section 2",
children: [{
title: "Section 2.1"
},
{
title: "Section 2.2"
}
]
},
{
title: "Section 3",
children: [{
title: "Section 3.1"
},
{
title: "Section 3.2",
children: [{
title: "Section 3.2.1"
},
{
title: "Section 3.2.2"
}
]
}
]
},
{
title: "Section 4",
children: [{
title: "Section 4.1",
children: [{
title: "Section 4.1.1",
children: [{
title: "Section 4.1.1.1"
}]
}]
}]
}];
const finalHeaders = [];
traverseColumnHeaders(configuredHeaders, -1); // first depth should start with 0
function traverseColumnHeaders(headers, parentDepth) {
headers.forEach(header => {
header.currentDepth = parentDepth + 1;
if (header.children) {
traverseColumnHeaders(header.children, header.currentDepth);
header.colspan = header.children.reduce((currentSum, child) => currentSum + child.colspan, 0); // sum of child colspans
header.rowspan = 1;
} else {
header.colspan = 1;
// header.rowspan = ... maximum depth - header.currentDepth ...
}
addHeaderToFinalHeaders(header);
});
}
function addHeaderToFinalHeaders({ currentDepth, title, rowspan, colspan }) {
const depthExistsInFinalHeaders = currentDepth in finalHeaders;
if (!depthExistsInFinalHeaders) {
finalHeaders[currentDepth] = [];
}
finalHeaders[currentDepth].push({ title, rowspan, colspan });
}
console.log(finalHeaders);
这个对我来说看起来不错,因为我只需要遍历集合一次。但正如你所见,一些rowspan 字段尚未计算,因为我不知道此时的最大深度。
为了解决这个问题,我可以初始化一个全局变量,像这样搜索最大深度
(我暂时从这里 Getting the depth of a tree data structure in a simpler way 获取解决方案)
function getMaximumDepth(headers) {
return getDepth(headers) -1;
};
function getDepth(headers) {
return 1 + Math.max(0, ...headers.map(({ children = [] }) => getDepth(children)));
}
const maximumDepth = getMaximumDepth(configuredHeaders);
计算
header.rowspan = maximumDepth - header.currentDepth
但现在我必须遍历结构两次。有没有办法优化我的解决方案?
【问题讨论】:
标签: javascript