Разделение динамического количества элементов на столбцы

У меня есть динамическое количество элементов, в которых мне нужно разделить на столбцы. Скажем, мне дано следующее:

array("one", "two", "three", "four", "five", "six", "seven", "eight") 

Мне нужно сгенерировать это:

 <ul> <li>one</li> <li>two</li> <li>three</li> <li>four</li> </ul> <ul> <li>five</li> <li>six</li> <li>seven</li> <li>eight</li> </ul> 

Вот несколько правил:

  • если нет предметов, я не хочу, чтобы что-то выплевывало
  • если есть 16 или менее 16 элементов, id, как 4 элемента на <ul>
  • если есть более 16 элементов, я бы хотел, чтобы он был равномерно распределен
  • мне придется в алфавитном порядке переупорядочить элементы. если есть 17 предметов, 17-й предмет должен будет перейти в первый столбец, но все нужно переупорядочить.

Что я до сих пор:

 function divide( $by, $array ) { 14 $total = count( $array ); 15 $return = array(); 16 $index=0; 17 $remainder = $total % $by !== 0; 18 $perRow = $remainder ? 19 $total / $by + 1: 20 $total / $by 21 ; 22 23 for ( $j = 0; $j<$by; $j++ ) { 24 //$return[] = array(); 25 26 if ( $index == 0 ) { 27 $slice = array_slice( $array, 0, $perRow ); 28 $index = $perRow; 29 $return[$j] = $slice; 30 } else { 31 $slice = array_slice( $array, $index, $perRow ); 32 $index = $index+$perRow; 33 $return[$j] = $slice; 34 } 35 } } 

Я подаю число, например divide (4, $ arrRef), число определяет количество столбцов, но мне нужно рефакторировать, чтобы он определял количество столбцов

Я использовал этот код внутри своего шаблона просмотра.

 <?php $col = 3; $projects = array_chunk($projects, ceil(count($projects) / $col)); foreach ($projects as $i => $project_chunk) { echo "<ul class='pcol{$i+1}'>"; foreach ($project_chunk as $project) { echo "<li>{$project->name}</li>"; }; echo "</ul>"; }; ?> 

Ваши требования довольно странные / неопределенные, но я думаю, что это делает то, что вы просите

 function columnize( array $set, $maxCols = 4 ) { if ( count( $set ) <= 16 ) { return array_chunk( $set, 4 ); } return array_chunk( $set, ceil( count( $set ) / $maxCols ) ); } 

Если я правильно вас понял, вы хотите разделить ваши предметы на четыре столбца «разумно», чтобы списки можно было логически читать, когда они размещались бок о бок. Если это так, это должно сделать трюк:

 function columnize($items, $columns = 4, $min_per_column = 4) { if(empty($items)) return array(); $result = array(); $count = count($items); $min_count = $min_per_column * $columns; if($count <= $min_count) { $columns = ceil($count / $min_per_column); } else { $per_column = floor($count / $columns); $overflow = count($items) % $columns; } for($column = 0; $column < $columns; $column++) { if($count <= $min_count) { $item_count = $min_per_column; } else { $item_count = $per_column; if($overflow > 0) { $item_count++; $overflow--; } } $result[$column] = array_slice($items, 0, $item_count); $items = array_slice($items, $item_count); } return $result; } 

Вы можете проверить его здесь:

http://www.ulmanen.fi/stuff/columnize.php

Непроверенные:

 function divide($by, $list, $order = 'c') { if (empty($list)) { return array(); } if (count($list) <= 16) { $by = 4; } $columnLists = array(); for ($cIndex = 0; $cIndex < $by; $cIndex++) { $columnLists[$cColumn] = array(); } switch ($order) { case 'r': foreach ($list as $cEntry) { $columnLists[$cColumn][] = $cEntry; $cColumn = ($cColumn + 1) % $by; } break; case 'c': default: $maxColumnHeight = intval(count($list) / $by) + (count($list) % $by > 0 ? 1 : 0); for ($cIndex = 0; $cIndex < $by; $cIndex++) { $columnLists[$cColumn] = array_slice($list, $cIndex * $maxColumnHeight, $maxColumnHeight); } break; } return $columnLists; }