And*_*rle 1 javascript algorithm
我有这样的数据结构,顺序可以是随机的
const table = [
['A', 'a', 0],
['A', 'a', 1],
['A', 'b', 0],
['B', 'a', 0],
['B', 'b', 1],
['B', 'b', 0],
]
Run Code Online (Sandbox Code Playgroud)
这应该像这样在 html 中呈现为分层表
<table>
<tr><td rowspan="3">A</td><td rowspan="2">a</td><td>0</td></tr>
<tr><td>1</td></tr>
<tr><td>b</td><td>0</td></tr>
<tr><td rowspan="3">B</td><td>a</td><td>0</td></tr>
<tr><td rowspan="2">b</td><td>0</td></tr>
<tr><td>1</td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)
我想知道什么是解决这个问题的有效方法。考虑过将列表转换为树,然后再转换回列表,但我不确定这是解决此问题的最佳方法。
将每个项目转换为具有 rowCount 的对象,并使用 0 表示前一个项目相同,因此不显示它。我不知道你正在使用什么视图绑定库,但在 Angular、Vue 或 React 中,绑定到表真的很容易。如果您使用纯 JavaScript 执行此操作,则必须在循环中创建 DOM 元素。
const table = [
['A', 'a', 0],
['A', 'a', 1],
['A', 'b', 0],
['B', 'a', 0],
['B', 'b', 1],
['B', 'b', 0],
];
const rowSpan = rows =>
rows.map((row, rowIndex) =>
row.map((item, colIndex) => ({ data: item, rowSpan: countRows(rows, rowIndex, colIndex) }))
);
const countRows = (rows, rowIndex, colIndex) => {
if (rowIndex > 0 && rows[rowIndex - 1][colIndex] === rows[rowIndex][colIndex]) {
return 0;
}
let count = 1;
while (count + rowIndex < rows.length && rows[rowIndex + count][colIndex] === rows[rowIndex][colIndex]) {
count++;
}
return count;
};
const tableElement = document.createElement('table');
rowSpan(table).forEach(row => {
const tr = document.createElement('tr');
tableElement.appendChild(tr);
row.forEach(item => {
if (item.rowSpan) {
const td = document.createElement('td');
td.rowSpan = item.rowSpan;
td.innerHTML = item.data.toString();
tr.appendChild(td);
}
});
});
document.body.appendChild(tableElement);Run Code Online (Sandbox Code Playgroud)
td {
border: 1px solid black;
vertical-align: top;
padding: 3px 10px;
}Run Code Online (Sandbox Code Playgroud)