树的递归,根据后代叶子节点数量决定当前节点所跨的行,深度优先适合此场景。
代码实现:http://jsrun.net/AXaKp/editfunction getRows (data) {
const result = []
const values = Object.values(data)
if (values.some(v => typeof v !== 'object' || !v || !Object.keys(v).length)) {
result.push([{
text: Object.keys(data).join(', '),
rowspan: 1
}])
return result
}
for (let k in data) {
const pathList = getRows(data[k])
if (pathList.length) {
const first = pathList[0]
first.unshift({
text: k,
rowspan: pathList.length
})
}
result.push(...pathList)
}
return result
}
function generateHtml (rows, head) {
return `
${ head.map(h => `
${h}`).join('') }${rows.map(r => {
return `
${r.map(({ text, rowspan }) => `
${text}`).join('')}`
}).join('\n')}
`
}
function render (data) {
const rows = getRows(data)
const head = (rows[0] || []).map(r => `Column-${r.text[0]}`)
const html = generateHtml(rows, head)
const div = document.createElement('div')
div.innerHTML = html
document.body.appendChild(div)
}
测试:render(data)
效果: