写出表格的结构html,一个面试题,根据json结构生成html表格

我的输入是

{

A1: {

B1: {

C1: {

D1: 1233,

D2: 11

},

C2: {

D1: 10,

D2: 10

}

},

B2: {

C1: {

D1: 10,

D2: 11

},

C2: {

D1: 10,

D2: 10

},

C3: {

D1: 10,

D2: 10

}

}

}

}

用什么框架都可以,只要求输出以下table, json的最后一个节点就是table的最后一个column,并且只能占据一行,也就是rowspan要为1.然后难点在于怎么判断前面的column占用的rowspan,我一点思路的都没有囧…

669330bb97fb882d5a65801eb0fa70cb.png

更新:

如果有代码演示最好了,底下评论的朋友谢谢了,我看了文章还是想不出来改怎么写代码…

回答:

树的递归,根据后代叶子节点数量决定当前节点所跨的行,深度优先适合此场景。

代码实现:http://jsrun.net/AXaKp/edit

function 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)

效果:

4ce0a77c4c3dc0c4732627f03a839e9f.png

回答:

这是一个树形结构,遍历这棵树,通过递归把每个节占据的行数算出来(就是每个子节点占据的行数之后)。然后你在渲染表格的时候就知道 rowspan 该是多少了(注意:如果为 1 可以省略哦)

给个提示

function calcRows(node) {

const keys = Object.keys(node);

const rowspan = node.rowspan = keys.reduce((sum, key) => sum + calcRows(node[key]), 0);

return rowspan;

}

回答:

把JSON对象视为树,表格的单元格就是节点,每一行就是节点的路径。这样每个单元格的rowSpan就是其路径的数量。

const data = {

A1: {

B1: {

C1: {

D1: 1233,

D2: 11

},

C2: {

D1: 10,

D2: 10

}

},

B2: {

C1: {

D1: 10,

D2: 11

},

C2: {

D1: 10,

D2: 10

},

C3: {

D1: 10,

D2: 10

}

}

}

}

// 利用递归方式的深度优先遍历算法计算每个节点的路径数量,并保持路径列表

function getPath(node, key) {

const pathList = Object.keys(node).reduce((pathList, key) => {

return pathList.concat(getPath(node[key], key));

}, [])

const pathCount = pathList.length;

pathList.map((path, index) => {

// 这里特殊处理下:只在第一条路径里插入当前节点key,其他路径不插入,方便生成`tr`

path.unshift(!!index ? null : { key, pathCount })

return path;

});

return pathList.length ? pathList : [[{ key, pathCount: 1 }]]

}

// 路径列表转成`tr`列表

function toTableRows(data) {

const pathList = getPath(data, 'root');

const rows = pathList.map((row, index) => {

const tr = ['

'];

for(let i = 1; i < row.length; ++i) {

if(row[i]) {

const { key, pathCount } = row[i];

tr.push(`

${key}`)

}

}

return tr.join('')

})

return rows.join('')

}

document.getElementById('table').innerHTML = toTableRows(data)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值