ユーザーと訪問したページのデータを示す HTML テーブルを作成する必要があります。for および/または foreach ループを使用するのは不格好に思えますが、これ以上良いものは思いつきません。私はPHPを使用していますが、これは言語に依存しないと思います。
8 に答える
複数の行があり、各行のデータが同様にフォーマットされている場合、ループを使用しないでテーブルを作成する方法は思いつきません。そのようなものは、基本的にループが発明されたものです。
作成したいテーブルの詳細をお知らせいただければ、より良い方法を策定できるかもしれません。
ループを回避することはおそらく不可能です。実装されていない場合でも、マシン レベルで発生します。
ただし、厄介なコードを使用せずに「純粋」に保ちたい場合は、少なくとも次のことを実行できます。
$tableformat = '<table><thead>%s</thead><tbody>%s</tbody></table>';
$rowformat = '<tr>%s</tr>';
$cellformat = '<td>%s</td>';
$hdata = '';
foreach( $data[0] as $cellname => $cellvalue )
{
$hdata .= sprintf( $cellformat, $cellname );
}
$hdata = sprintf( $rowformat, $hdata );
$rdata = "";
foreach( $data as $rownum => $rowvalue )
{
$row = "";
foreach( $rowvalue as $colname => $colvalue )
{
$row .= sprintf( $cellformat, $colvalue );
}
$rdata .= sprintf($rowformat,$row);
}
return sprintf( $tableformat, $hdata, $rdata );
少なくともそのようにすると、ある程度保守可能になる可能性があります。不完全な文字列についてあまり心配する必要はありません。
そのコードの一部を次のように置き換えることもできます
$hdata = "<tr><td>" . implode( "</td><td>", array_keys( $data[0] )) . "</td></tr>";
$rdata .= "<tr><td>" . implode( "</td><td>", $rowvalue ) . "</td></tr>";
これはかなり簡潔ですが、最終的には少しお湯に浸かる可能性があり、再コーディングが必要になります。(そして implode は内部的にループを実行するので、これは Loose-Lose です)。
余分な関数呼び出し (およびまだ実行中のループ) のオーバーヘッドを気にしない場合、これにより、あまり多くのネガを使用せずに、より簡潔なコードを作成できます。
$tableformat = '<table><thead>%s</thead><tbody>%s</tbody></table>';
$rowformat = '<tr>%s</tr>';
$cellformat = '<td>%s</td>';
function tr( $cells )
{
$o = "";
foreach( $cells as $i => $v )
{
$o .= sprintf( $cellformat, $v );
}
return sprintf( $rowformat, $o );
}
return sprintf( $tableformat,
tr( array_keys($data[0])),
implode("", array_map( 'tr', $data )) );
しかし気をつけてください、それは読みにくいです、そしてあなたはいつの日か Lisp で目覚めるでしょう。
ある種のループを使用しない場合は、コード内の行と列の数をハードコーディングする必要があります。これはおそらく、はるかに悪い考えです。
PHP 用のSmartyテンプレート エンジンを強くお勧めします。これにより、Smarty 構文を使用して、テーブル (および避けられない関連するループ) をテンプレートに移動できるため、ビジネス ロジックからより明確に分離されます。サンプルのほぼすべてのコードを、HTML スニペットのいくつかの単純なタグに置き換えることができます。テーブルの使用例については、Smarty ページの短期集中コースを参照してください。
テーブル内のデータが動的である場合は、ループを使用する必要があります。テーブルを生成するコンポーネントを取得したとしても、内部的にはループを使用します。
それはあなたの「最高」の定義に依存します。FOR ループは問題なく機能します。私は PHP プログラマーではありませんが、.NET では、テーブル HTML を宣言するために使用できる一種のテンプレートである Repeater を使用できます。ヘッダー、フッター、各項目のテンプレートがあります。データ ソースをリピーターにバインドすると、FOR ループを使用するよりも少しエレガントにテーブル HTML が生成されます。PHP には、何らかのテンプレートに相当するものがあるのではないかと思います。
ただし、最終的にはリピーターでさえ何らかのループを使用します...
なぜループを避けたいのですか?アイテムのセットがあり、各アイテムを表示したい場合、セットをループすることは明らかな解決策ですか?
ビューからモデルを分離しようとしている場合、またはより読みやすいコードを記述している場合は、それで問題ありません。しかし、ループは本質的に悪いものではありません。
私は通常ループを使用しますが、implode
これにはPHPで使用します。関数型プログラミングをサポートする言語では、私はそれを別の方法で行います。
function render_table($data) {
$html = '<table>';
$tr = array();
foreach (array_keys($data[0]) as $key) {
$tr[] = '<th>' . htmlspecialchars($key) . '</th>';
}
$html .= "\n" . '<thead>' . "\n" . '<tr>' . "\n" . implode("\n", $tr) . '</tr>' . '</thead>';
$tbody = array();
foreach ($data as $row) {
$tr = array();
foreach ($row as $value) {
$tr[] = '<td>' . htmlspecialchars($value) . '</td>';
}
$tbody[] = '<tr>' . "\n" . implode("\n", $tr) . '</tr>';
}
$html .= "\n" . '<tbody>' . "\n" . implode("\n", $tbody) . '</tbody>';
$html .= '</table>';
return $html;
}