前回までの記事
概要
前回までと比べて、処理とコードを簡潔に。
そして、取得データをテキストに限らず任意の関数で自由に取得できるように変更。
コード
const getTable = (table, func) => {
const collector = []
const tableRows = table.rows
const numOfCols = ((cnt, i) => {
const headerCells = tableRows[0].cells
while (++i < headerCells.length) cnt += headerCells[i].colSpan
return cnt
})(0, -1)
const rowspanCounter = Array(numOfCols).fill(0)
let pointY = 0, pointX, cellIndex, copiedTimes
for (const numOfRows = tableRows.length; pointY < numOfRows; pointY++) {
const columns = []
const tr = tableRows[pointY]
for (pointX = cellIndex = 0; pointX < numOfCols; pointX++) {
if (rowspanCounter[pointX]) {
columns.push( collector[pointY - 1][pointX] )
rowspanCounter[pointX]--
continue
}
const td = tr.cells[cellIndex],
edited = func(td, tr),
rowSpan = td.rowSpan,
colSpan = numOfCols < td.colSpan + pointX ? numOfCols : td.colSpan
for (copiedTimes = 0; copiedTimes < colSpan;) {
columns.push(edited)
rowspanCounter[pointX + copiedTimes++] += rowSpan - 1
}
pointX += colSpan - 1
cellIndex++
}
collector.push(columns)
}
return collector
}
const table = getTable(document.getElementsByTagName('table')[0], cell => cell.textContent)
console.table(table)
第一引数に対象のテーブルを指定。
第二引数に各セルを処理する関数。
セル処理用関数の引数は
1.処理するTD
2.処理するTDの親要素TR
となります。
追記
const getTable = (tbl,fn) => {
const arr = Array.from({length:tbl.rows.length},() => [])
,maxCol = [...tbl.rows[0].cells].reduce((n,z) => n + z.colSpan,0)
for(let y=0,x=0;y<tbl.rows.length;y++,x=0){
const tr = tbl.rows[y].cells
for(const td of tr){
const elm = fn(td,tr)
for(;x<maxCol;x++){
if(x in arr[y] === false) break
}
for(let p=0;p<td.colSpan;p++,x++){
if(x>=maxCol) break
for(let q=0;q<td.rowSpan;q++) arr[y+q][x] = elm
}
}
}
return arr
}
const table = getTable(document.getElementsByTagName('table')[0], cell => cell.textContent.trim())
console.table(table)