【问题标题】:Dividing up a dynamic number of items into columns将动态数量的项目划分为列
【发布时间】:2012-11-20 19:10:40
【问题描述】:

我有一个动态数量的项目,我需要将这些项目分成几列。假设我得到了这个:

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 像每个 &lt;ul&gt; 4 个项目
  • 如果超过 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),这个数字决定了列数,但我需要重构它来确定列数

【问题讨论】:

  • 有趣的问题。我建议您不要立即接受答案,因为用一个非常好的答案来回答这个问题可能需要一些时间。
  • "如果超过 16 件,我希望它均匀分布"?定义“均匀分布”。
  • 您的条件不是自洽的 re:排序。您希望连续项目按行顺序(由示例暗示)还是按列顺序(通过“如果有 17 个项目,第 17 个项目将需要转到第一列”来暗示)
  • 正如 Karl 所建议的,我认为应该有更多的规则。例如,如果有 100 个项目,应该有多少列? 4、5、10 等等...?
  • 这是一个很常见的问题,实际上是分页。

标签: php pagination


【解决方案1】:

我在视图模板中使用了这段代码..

<?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>";
}; ?>

【讨论】:

    【解决方案2】:

    您的要求非常奇怪/含糊,但我认为这可以满足您的要求

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

    【讨论】:

    • 虽然我认为这应该在函数之外完成,但出于 OP 的目的,在函数内也进行数组排序可能是个好主意。
    【解决方案3】:

    如果我对您的理解正确,您希望将您的项目“智能”分成四列,以便在并排放置时可以逻辑地阅读列表。如果是这样的话,这应该可以解决问题:

    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

    【讨论】:

      【解决方案4】:

      未经测试:

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-22
        • 2017-01-14
        • 2015-11-10
        • 1970-01-01
        • 2015-01-21
        相关资源
        最近更新 更多