Являются ли циклы лучшим способом построения таблицы? - PullRequest
2 голосов
/ 05 ноября 2008

Мне нужно создать таблицу HTML, которая отображает данные о пользователях и посещенных страницах. Кажется, что klunky использовать для и / или циклов foreach, но я не могу придумать ничего лучшего. Я использую PHP, но я предполагаю, что это не зависит от языка.

Ответы [ 8 ]

4 голосов
/ 05 ноября 2008

Избежать циклов, вероятно, невозможно, если не в реализации, то это все равно произойдет на уровне машины.

Однако, если вы хотите остаться «чистым» без неприятного кода, вы можете, по крайней мере, сделать:

$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>"; 

Что, будучи довольно лаконичным, возможно, в конечном итоге приведет вас к небольшому количеству горячей воды, и потребуется перекодировка. (и внутренне запускает цикл, так что это проигрыш).

Если вы не возражаете против дополнительных вызовов функций (и все еще работающих циклов), это может сделать более лаконичный код без слишком большого количества негативов:

 $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 )) ); 

Но будьте осторожны, это трудно читать, и вы продолжите в том же духе, когда однажды проснетесь с недоумением.

4 голосов
/ 05 ноября 2008

Что ж, если у вас есть несколько строк с одинаковым форматированием данных в каждой строке, я не могу придумать, как создать таблицу, избегающую использования цикла. Этот тип вещей - в основном то, для чего были изобретены петли.

Если вы предоставили нам более подробную информацию о таблице, которую хотите построить, возможно, мы сможем сформулировать лучший метод.

3 голосов
/ 05 ноября 2008

Если вы не используете какой-то цикл , то вам нужно жестко закодировать количество строк и столбцов в вашем коде, что, вероятно, гораздо хуже

2 голосов
/ 05 ноября 2008

Я настоятельно рекомендую шаблонизатор Smarty для PHP. Это позволит вам переместить вашу таблицу (и связанный с ней цикл, который неизбежен) в шаблон с использованием синтаксиса Smarty, чтобы он был более понятным и более отделенным от вашей бизнес-логики. Вы сможете заменить почти весь код в вашем примере несколькими простыми тегами в HTML-фрагменте. Ознакомьтесь с курсом ускоренного обучения на странице Smarty для примера использования таблицы.

2 голосов
/ 05 ноября 2008

Если данные в таблице являются динамическими, то вы должны использовать цикл. Даже если вы получите компонент, который генерирует таблицу для вас, внутри он будет использовать цикл.

1 голос
/ 05 ноября 2008

Это зависит от вашего определения «лучший». Циклы FOR сделают эту работу просто отлично. Я не программист PHP, но в .NET вы можете использовать Repeater, своего рода шаблон, который вы можете использовать для объявления таблицы HTML. Он имеет шаблоны для верхнего, нижнего колонтитула и каждого элемента. Вы привязываете источник данных к повторителю, и он сгенерирует для вас таблицу HTML более элегантно, чем использование циклов FOR. Я полагаю, что в PHP может быть какой-то шаблонный эквивалент.

В конце концов, даже Ретранслятор использует какой-то цикл ...

0 голосов
/ 05 ноября 2008

Почему вы хотите избежать петель? Если у вас есть набор элементов, и вы хотите отобразить каждый элемент, то, безусловно, циклический просмотр набора является очевидным решением?

Если вы пытаетесь отделить модель от вида или пишете более читаемый код, хорошо; но петли не плохие по своей природе.

0 голосов
/ 05 ноября 2008

Я обычно использую циклы и 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;
}
...