Home About Contact
TypeScript , Underscore.js , HTML

リストから 任意の列数を持つ HTML テーブルを生成する

リストを n 個ごとに分割する ファイナルアンサー の応用例です。

ポケモンリストをHTMLテーブルに変換するのですが、 クライアントブラウザの幅に応じて 3列とか5列に切り替えたいとする・・・ということを考えます。

TypeScript で書く。実行は Deno を使います。

$ deno --version
deno 2.4.1 (stable, release, x86_64-unknown-linux-gnu)
v8 13.7.152.6-rusty
typescript 5.8.3

Underscore.js を使うので、プロジェクトディレクトにそれを入れておく:

$ deno add npm:underscore

それではコードを書きます。

//
// main.ts
//

import _ from 'underscore'

const take = <T>(n: number, l: T[]) => {
    return l.slice(0, n)
}

const drop = <T>(n: number, l: T[]) => {
    return l.slice(n)
}

const group = <T>(n: number, l: T[]) => {
    if (l.length==0) {
        return []
    } else {
        return [take(n, l)].concat( group(n, drop(n,l)) )
    }
}

ここまでは前回書いたコード。 そしてこの group を使って ポケモン名のリストから HTML テーブルを生成するための関数 toHtml を書きます。

const toHtml = (n: number, pokemonNameList: string[]): string => {
    const pokemonListList = group(n, pokemonNameList)
    
    const tableBody: string[][] = pokemonListList.map((pokemonList)=>{
        const row: string[] = pokemonList.map((pokemon)=> {
            return `<td>${pokemon}</td>`
        })
        return ['<tr>'].concat( row ).concat(['</tr>'])
    })
    
    return ['<table><tbody>'].concat( _.flatten(tableBody) ).concat( ['</tbody></table>'] ).join('\n')
}

たとえば、3列のテーブルを出力したい場合:

const list = [
    'eevee',
    'pidgeot',
    'pikachu',
    'voltorb',
    'squirtle',
    'golduck',
    'charmander',
    'golem',
    'charizard',
    'metapod',
    'butterfree']

console.log(toHtml(3, list))

deno run します。

$ deno run main.ts

出力されたHTML:

<table><tbody>
<tr>
<td>eevee</td>
<td>pidgeot</td>
<td>pikachu</td>
</tr>
<tr>
<td>voltorb</td>
<td>squirtle</td>
<td>golduck</td>
</tr>
<tr>
<td>charmander</td>
<td>golem</td>
<td>charizard</td>
</tr>
<tr>
<td>metapod</td>
<td>butterfree</td>
</tr>
</tbody></table>

できました。

ブラウザでレンダリングするとこんな感じ:

3 columns

今度は 5列を指定して出力してみます。

console.log(toHtml(5, list))

出力されたHTML:

<table><tbody>
<tr>
<td>eevee</td>
<td>pidgeot</td>
<td>pikachu</td>
<td>voltorb</td>
<td>squirtle</td>
</tr>
<tr>
<td>golduck</td>
<td>charmander</td>
<td>golem</td>
<td>charizard</td>
<td>metapod</td>
</tr>
<tr>
<td>butterfree</td>
</tr>
</tbody></table>

ブラウザでレンダリングするとこんな感じ:

5 columns

以上です。