Заполнение равномерно распределенной матрицы массивов с помощью PHP - PullRequest
1 голос
/ 19 октября 2010

У меня есть массив объектов, содержащий списки раз. Я должен вставить это в матричный аналог массива, чтобы поместить его в таблицу. Это часть моего ранее SO вопроса о том, как строить календарные таблицы

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

Они представляют собой таблицу playdates фильмов. Как можно увидеть в действии здесь . Код для этого прямо сейчас слишком сложен (ИМХО) и может быть упрощен, просто я не знаю как. Может быть, через какую-нибудь Matrix-библиотеку? Или какой-то алгоритм, о котором я не знаю?

Результирующая структура должна быть массивом, представляющим заголовок (имена столбцов таблицы) и массивом с массивами, представляющими строки. Следующим образом:

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

В каждой строке должно быть одинаковое количество «ячеек». Метки времени должны быть сгруппированы по часу, к которому они принадлежат (16:15, 16:30 и т. Д. Все сгруппированы до 16:00) Также обратите внимание, что приведенная выше структура вывода также может быть оптимизирована, пожалуйста, дайте мне знать, если есть способы упростить код, упростив или изменив полученную «матрицу».

Псевдокод для того, что я делаю сейчас:

  1. узлов usort $ по названию
  2. переберите все $ узлы, чтобы найти ширину матрицы (с 14:00 до 17:00) и заполните $header
  3. снова зациклите все $ узлы, для каждого узла зациклите над $ header и заполните массив пустыми значениями ('') или временными метками.

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

1 Ответ

0 голосов
/ 19 октября 2010

Я проверяю вашу информацию и придумываю, как бы это сделать, в надежде, что это поможет вам.

Сначала получите данные в этом формате:

$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>
...