LoginSignup
0
1

More than 3 years have passed since last update.

【JS】表 (table)のHTMLを2次元配列に変換するプログラム

Last updated at Posted at 2020-11-30

tableタグを2次元で表現するプログラムを作成する。
rowspanやcolspanも加味して考える。

目次

・セルを1で表現するプログラム
・列番号で表現するプログラム


1. セルを1で表現するプログラム

実際のブラウザ上の表示に合わせて、セルがある場所を1で埋めて表を表現する。

完成イメージ

例えば3行3列の表なら以下のように出力する。

image.png

arr = [
  [1, 1, 1]
  [1, 1, 1]
  [1, 1, 1]
]



▼結合がある場合1

結合がある場合セルの数(tdタグ)は減るが、colspanやrowspanに合わせて1を埋める。

image.png

arr = [
  [1, 1, 1]
  [1, 1, 1]
  [1, 1, 1]
]



▼結合がある場合の例2

image.png

arr = [
  [1, 1, 1]
  [1, 1, 1, 1]
  [1, 1, 1, 1, 1]
]

コード

処理には、HTMLTableElementを利用する。

HTMLTableElementはtableタグをオブジェクトに変換しjsで処理できるAPI。

HTMLTableElementの使い方


function scanTable(table)
{
    var arr = [];
    for(var y=0; y<table.rows.length; y++)
    {
        var row = table.rows[y];

        for(var x=0;x<row.cells.length;x++)
        {
            var cell = row.cells[x], xx = x, tx, ty;

            for(; arr[y] && arr[y][xx]; ++xx);                        

            for(tx = xx; tx < xx + cell.colSpan; ++tx)            
            {
                for(ty = y; ty < y + cell.rowSpan; ++ty)
                {
                    if( !arr[ty] ) arr[ty] = [];                    
                    arr[ty][tx] = 1;
                }
            }
        }
    }

    return arr
};

コードの中身

▼変数

arr 1が入る2次元配列。最終的なアウトプット。

ty 1を入力する行番号

tx 1を入力する列番号

y 行番号

x 列番号

xx 1を入力するセルの列開始番号。



▼主な処理

for(var y=0; y<table.rows.length; y++)
    {
        var row = table.rows[y];

        for(var x=0;x<row.cells.length;x++)

1行毎、1セル毎に処理を繰り返す。
x, yは結合を加味せず、1づつ増えていく。



for(; arr[y] && arr[y][xx]; ++xx);
1を挿入しようとしているセルに、結合などにより既に1が挿入されていないか判断。

既に1が挿入してある場合は、隣のセルに移動(xxを1増やす)

for(tx = xx; tx < xx + cell.colSpan; ++tx)
列方向の結合状況を加味する処理。cospanの分だけ、列方向に1を入力するセルを増やす。

for(ty = y; ty < y + cell.rowSpan; ++ty)
行方向の結合状況を加味する処理。rowspanの分だけ、行方向に1を入力するセルを増やす。

if( !arr[ty] ) arr[ty] = [];
行方向の結合(rowspan > 1)があった場合に、まだその行が定義されていない場合は、空のオブジェクトを生成する。

これがないと、rowspan > 1 の時にエラーが発生する。

エラー
Cannot set property '0' of undefined

//undefinedのプロパティ0には値をセットできない


2. 列番号で表現するプログラム

結合によりセルの列番号がズレるが、ズレが発生した場合に各セルの見た目の列番号を取得するプログラム。

先ほどは見た目を1で表現したが、今回はセルを基準にして表示する。

完成イメージ

image.png

arr = [ 
 [0, 1, 2]
 [0, 1, 2]
 [0, 1, 2]
]



▼結合がある場合1
image.png

arr = [ 
 [0, 1, 2]
 [1, 2]
 [0, 1, 2]
]

2行目のセルが2つになっている状態。実際のセルの行列番号は (1, 0) だが、見た目の列番号は1から始まる。



▼結合がある場合2
image.png

arr = [ 
 [0, 1, 2]
 [1, 2, 3]
 [0, 3, 4]
]

コード

function scanTable2(table)
{
    var arr = [];
    const colIndices = [];
    for(var y=0; y<table.rows.length; y++)
    {
        var row = table.rows[y];

        for(var x=0;x<row.cells.length;x++)
        {
            var cell = row.cells[x], xx = x, tx, ty;

            for(; arr[y] && arr[y][xx]; ++xx);                        // skip already occupied cells in current row

            for(tx = xx; tx < xx + cell.colSpan; ++tx)            // arrark arratrix elearrents occupied by current cell with true
            {
                for(ty = y; ty < y + cell.rowSpan; ++ty)
                {
                    if( !arr[ty] ) arr[ty] = [];                    // fill arrissing rows
                    arr[ty][tx] = 1;

                    if ( !colIndices[y] ) colIndices[y] = [];
                    colIndices[y][x] = xx;
                }
            }
        }
    }
    return colIndices;
};

9割は前述の表を1で表現するプログラムと同じ。追加した処理は以下3行のみ。

追加コード
const colIndices = [];

if ( !colIndices[y] ) colIndices[y] = [];
colIndices[y][x] = xx;

列番号を格納する変数colIndicesを作成し、セル番号に合わせて、変数xxを格納している。

x = row.cells.lengthであり、何番目のセルかを表している。

xxは配列arrで1を格納するセルの開始番号を表してる。つまり結合によりセルがズレていれば、ズレも加味した列数を指す値となっている。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1