代码之家  ›  专栏  ›  技术社区  ›  berkes

用PHP填充均匀分布的数组矩阵

  •  1
  • berkes  · 技术社区  · 14 年前

    earlier SO question on how to build calendar tables

    $node->sessions = array(
      1286452800, // '2010-10-07 14:00:00'
      1286460000, // '2010-10-07 16:00:00'
    );
    $node->title = 'Foo';
    $nodes[1] = $node;
    
    $node->sessions = array(
      1286452800, // '2010-10-07 14:00:00'
      1286460000, // '2010-10-07 16:00:00'
      1286461800, // '2010-10-07 16:30:00'
    );
    $node->title = 'Bar';
    $nodes[2] = $node;
    
    $node->sessions = array(
      1286460000, // '2010-10-07 16:00:00'
      1286461800, // '2010-10-07 16:30:00'
      1286465400, // '2010-10-07 17:30:00'
    );
    $node->title = 'Baz';
    $nodes[3] = $node;
    

    这些代表了电影的播放日期表。从行动上看 here

    结果结构应该是一个表示头(表的列名)的数组和一个包含表示行的数组的数组。具体如下:

    $header = array(
      ' ', // empty "cell"
      ttt, // ttt being the timestamp for '14:00'
      uuu, // idem for '15:00'
      vvv, // idem for '16:00'
      www, // idem '17:00'
    );
    //  title, 14:00, 15:00, 16:00, 17:00
    $rows = array(
      array(
        'Bar', 1286452800,  '', array(1286460000, 1286461800), '',  //Both 16:00 and 16:30 grouped under 16:00 'header'
      ),
      array(
        'Baz', '',  '', array(1286460000, 1286461800), 1286465400
      ),
      array(
        'Foo', 1286452800,  '', 1286460000,  '',
      )  
    );
    

    每行应该有相同数量的“单元格”。 还请注意,上面给出的输出结构可能也会得到优化,请告诉我是否有方法通过简化或更改生成的“矩阵”来简化代码。

    1. usort$按标题列出的节点
    2. 循环所有$nodes以查找矩阵的宽度(14:00到17:00),并填充 $header
    3. 再次循环所有的$nodes,对于每个节点循环$header,并用其中一个清空填充数组 ('') 或者有时间戳。

    现在,对于上面的三个条目,这不是一个大问题,但是这个矩阵可以变得非常宽(大的$headers数组)和很深(许多$nodes),从而导致大量重复循环。 但性能和重复循环并不是我最关心的,主要是拥有更干净、更少嵌套、更少复杂的代码。:)

    1 回复  |  直到 7 年前
        1
  •  0
  •   Galen    14 年前

    我正在取消你的计划,并提出我将如何做,希望它能帮助你。

    首先获取以下格式的数据:

    $movies = array (
        array (
            'title' => 'Babies',
            'times' => array(
                        1286460000,1286467200,1286476200,1286487000
            )
        ),
        array (
            'title' => 'El secreto de sus ojos',
            'times' => array(
                        1286474400,1286481600,1286483400
            )
        )
        // more movies...
    );
    

    以下是工作代码的链接: http://ideone.com/P4zZn

    这是密码

    <?php
    date_default_timezone_set('GMT');
    $start_hour = 12; // Start hour of matrix
    $end_hour = 22; // End hour of matrix
    $skip_hours = array( 18, 20 );
    
    // Get the timestamp for each hour in the matrix
    foreach( range( $start_hour, $end_hour ) as $hr ) {
        if ( in_array( $hr, $skip_hours ) ) {
            continue;
        }
        $time_sections[] = mktime( $hr,0,0, 10, 7, 2010 ); // You'll want to put null or the month/day to use the current month/day
    }
    
    $movies = array (
        array (
            'title' => 'Babies',
            'times' => array(
                        1286460000,1286467200,1286476200,1286487000
            )
        ),
        array (
            'title' => 'El secreto de sus ojos',
            'times' => array(
                        1286474400,1286481600,1286483400
            )
        )
    );
    
    
    ?>
    
    <table border="1">
        <thead>
            <th>Movie</th>
            <?php foreach( $time_sections as $time_section ): ?>
            <th><?php echo date( 'G:i', $time_section ) ?> </th>
            <?php endforeach; ?>
        </thead>
        <tbody>
        <?php foreach( $movies as $movie ): ?>
            <tr>
                <td><?php echo $movie['title'] ?></td>
                <?php foreach( $time_sections as $time_section_index => $time_section ): ?>
                <td>
                    <!-- while there are movie times left and the first movie time in the array is less than the next timestamp print the movie time -->
                    <?php while( count( $movie['times'] ) && current( $movie['times'] ) < $time_sections[$time_section_index + 1] ): ?>
                        <!-- echo the time and pull it from the array -->
                        <?php echo date( 'G:i', array_shift( $movie['times'] ) ) ?> 
                    <?php endwhile; ?>
                </td>
                <?php endforeach; ?>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>