I have a dynamic number of items in which I'll need to divide into columns. Let's say I'm given this:
array("one", "two", "three", "four", "five", "six", "seven", "eight")
I need to generate this:
<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>
Here are some rules:
- if there are no items, I don't want anything to be spat out
- if there are 16 or under 16 items, id like 4 items per
<ul>
- if there are more than 16 items, i'd like it to be spread out evenly
- i'll have to alphabetically reorder items. if there are 17 items, the 17th item will need to go to the first column but everything needs to be reordered.
What I have so far:
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 }
}
I feed a number, like divide( 4, 开发者_JAVA百科$arrRef ), the number dictates the # of columns, but I need to refactor so it determines the number of columns
I used this code inside my view template..
<?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>";
}; ?>
Your requirements are pretty weird/vague, but I think this does what you're asking
function columnize( array $set, $maxCols = 4 )
{
if ( count( $set ) <= 16 )
{
return array_chunk( $set, 4 );
}
return array_chunk( $set, ceil( count( $set ) / $maxCols ) );
}
If I understood you correctly, you are looking to divide your items into four columns "intelligently" so that the lists can be read logically when placed side by side. If that is the case, this should do the trick:
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;
}
You can test it here:
http://www.ulmanen.fi/stuff/columnize.php
Untested:
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;
}
精彩评论