Распечатайте данные трехмерного массива в виде HTML-таблицы временных диапазонов в день

У меня есть многомерный массив, как показано ниже. Я хотел бы отобразить данные в таблице, где каждый день недели и время его открытия и закрытия будут в одной строке. Ожидаемый результат таблицы прилагается ниже.

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

$times = [
    "opening_time" => [
        "monday" => ["10:30 am", "6:30 pm"],
        "tuesday" => ["12:30 pm"],
        "wednesday" => ["4:30 pm"],
        "thursday" => ["2:30 pm"],
        "friday" => ["4:00 pm"],
        "saturday" => ["6:00 am"],
        "sunday" => []
    ],
    "closing_time" => [
        "monday" => ["6:00 pm", "10:30 pm"],
        "tuesday" => ["7:00 pm"],
        "wednesday" => ["10:00 pm"],
        "thursday" => ["6:30 pm"],
        "friday" => ["11:00 pm"],
        "saturday" => ["6:00 pm"],
        "sunday" => []
    ]
];
 

Всегда ли у вас будет такая схема (двухчастный рабочий день) или бывают случаи, когда у вас их больше двух или только одна?

FiddlingAway 06.04.2024 11:10

@FiddlingAway временных интервалов может быть более двух, поэтому мне нужно решение, которое распечатывало бы все интервалы.

Sylvester Loh 06.04.2024 15:29

@FiddlingAway Под слотом я подразумеваю пару часов открытия и закрытия (например, с 10:00 до 18:00). В предоставленном массиве понедельник будет иметь 2 временных интервала, воскресенье — 0, а остальные дни — по 1.

Sylvester Loh 06.04.2024 15:38

Я скорректировал код в соответствии с вашими требованиями. Взгляни, пожалуйста.

FiddlingAway 06.04.2024 17:37

Если можно, то ответ @mickmackusa лучше, чем тот, который я предложил. Вы бы вместо этого были против того, чтобы принять это как ответ?

FiddlingAway 08.04.2024 12:35

@FiddlingAway Вместо этого я принял ответ mickmackusa. Спасибо всем!

Sylvester Loh 08.04.2024 20:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
6
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете сделать это вот так. Пожалуйста, прочитайте комментарии внутри кода и примечания под выводом.

<?php
function renderSlots($columns,$repacked,$day,$time) {
    $html = '';
    for($i = 0; $i < $columns; $i++) {
        // Check if slot i is set
        if (isset($time[0][$i])) {
            $html .= '
                <td>'.$time[0][$i].' to '.$repacked[$day]["closing_time"][0][$i].'</td>
            ';
        } else {
            $html .= '
                <td></td>
            ';
        }
    }

    return $html;
}

$times = [
    "opening_time" =>[
        "monday" => [
            0 => "10:00 am",
            1 => "6:30 pm",
            2 => "some other time"
        ],
        "tuesday" => [
            0 => "12:30 pm"
        ],
        "wednesday" => [
            0 => "4:30 pm"
        ],
        "thursday" => [
            0 => "2:30 pm"
        ],
        "friday" => [
            0 => "4:00 pm"
        ],
        "saturday" => [
            0 => "6:00 am"
        ],
        "sunday" => []
    ],
    "closing_time" => [
        "monday" => [
            0 => "6:00 pm",
            1 => "10:30 pm",
            2 => "some other closing time"
        ],
        "tuesday" => [
            0 => "7:00 pm"
        ],
        "wednesday" => [
            0 => "10:00 pm"
        ],
        "thursday" => [
            0 => "6:30 pm"
        ],
        "friday" => [
            0 => "11:00 pm"
        ],
        "saturday" => [
            0 => "6:00 pm"
        ],
        "sunday" => []
    ]
];

// Repacking your original array to be like this
/*
    $arr = [
        day => [
            opening_time => [
                10:00 am
                6:30 pm
            ],
            closing_time => [
                6:00 pm
                10:30 pm
            ]
        ]
        ...
    ];
*/

$repacked = [];

// This is to determine the number of columns we'll need
// Letters a-g are variables, standing in for the number of
// slots in a day
/*
$arr = [
    "monday" => a,
    "tuesday" => b,
    "wednesday" => c,
    "thursday" => d,
    "friday" => e,
    "saturday" => f,
    "sunday" => g 
];
*/
$daySlots = [];


foreach($times as $type=>$days) {
    foreach($days as $day=>$time) {
        if (!isset($repacked[$day][$type])) {
            $repacked[$day][$type] = [];
        }

        $repacked[$day][$type][] = $time;

        if (!isset($daySlots[$day])) {
            $daySlots[$day] = 0;
        }

        $daySlots[$day] = count($time);
    }
}

// Get the max number of work slots
$columns = max($daySlots);

$html = '
    <table>
        <thead>
            <tr>
                <th>Day</th>
';

// As many columns as there are slots
for($i = 1; $i <= $columns; $i++) {
    $html .= '
        <th>Working hours '.$i.'</th>
    ';
}

$html .= '
            </tr>
        </thead>
        <tbody>
';

// Loop through days...
foreach($repacked as $day=>$times) {
    $html .= '
            <tr>
                <td>'.ucfirst($day).'</td>
    ';

    // ... then through specific opening times
    foreach($times as $type=>$time) {
        // We've already picked this up during one of
        // the previous loop passes, we don't need it now
        if ($type === "closing_time") {
            continue;
        }

        // Skip days with no set time - generate $columns number of cells
        if (!$time[0]) {
            $html .= str_repeat('<td></td>'.PHP_EOL,$columns);
            continue;
        }

        // With the outline of the repacked array given in 
        // lines 72-81, $time[0][0] is, in the first run through
        // the loop:
        /*
            $repacked
                $day (e.g. Monday)
                    $type (e.g. opening_time)
                        $time (a nested array, e.g. [ [10:00 am, 6:30 pm] ])
                            $time[0] ( first element of the nested array, e.g. [10:00 am, 6:30 pm] )
                                $time[0][1] (first time, e.g. 10:00 am)
        */

        // Check the slots, and generate columns
        $html .= renderSlots($columns,$repacked,$day,$time);
        
    }

    $html .= '
            </tr>
    ';
}

$html .= '
        </tbody>
    </table>
';

echo $html;
?>

Код выше выводит (дословно, пустые строки и все такое):

    <table>
        <thead>
            <tr>
                <th>Day</th>

        <th>Working hours 1</th>
    
        <th>Working hours 2</th>
    
        <th>Working hours 3</th>
    
            </tr>
        </thead>
        <tbody>

            <tr>
                <td>Monday</td>
    
                <td>10:00 am to 6:00 pm</td>
            
                <td>6:30 pm to 10:30 pm</td>
            
                <td>some other time to some other closing time</td>
            
            </tr>
    
            <tr>
                <td>Tuesday</td>
    
                <td>12:30 pm to 7:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Wednesday</td>
    
                <td>4:30 pm to 10:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Thursday</td>
    
                <td>2:30 pm to 6:30 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Friday</td>
    
                <td>4:00 pm to 11:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Saturday</td>
    
                <td>6:00 am to 6:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Sunday</td>
    <td></td>
<td></td>
<td></td>

            </tr>
    
        </tbody>
    </table>

Проверьте это здесь.


Примечания

Я переупаковал исходный массив, чтобы его было проще обработать и сгенерировать строку HTML для последующей обработки. Перепаковки можно было бы избежать, если бы вы контролировали способ формирования исходной таблицы (той, которую я назвал $times в предоставленном коде).

Отрисованная HTML-таблица представляет собой базовую таблицу: вы можете предоставлять классы CSS по мере ее прохождения или в открывающей части переменной $html, которая содержит thead и tbody.

Кроме того, если вам нужно стилизовать непустые (или пустые) ячейки таблицы, вы также можете сделать это с помощью классов CSS.

Код был скорректирован с учетом вашего комментария: теперь вы можете предоставить N рабочих слотов в течение дня.

Ответ принят как подходящий

На мой взгляд, в ответе @FiddlingAway слишком много циклов. Вам понадобится один подготовительный цикл, чтобы подсчитать количество необходимых временных интервалов на неделю. Затем вам понадобится вложенный цикл для обхода только данных о времени открытия.

Просматривая время открытия, получайте доступ к соответствующему времени закрытия по их общему ключу дня и индексу.

Код: (Демо)

$slots = max(array_map('count', $times['opening_time']));
echo '<table>';
foreach ($times['opening_time'] as $day => $opens) {
    echo "<tr><td>$day</td>";
    for ($i = 0; $i < $slots; ++$i) {
        printf(
            '<td>%s</td>',
            isset($opens[$i], $times['closing_time'][$day][$i])
                ? "{$opens[$i]} to {$times['closing_time'][$day][$i]}"
                : ''

        );
    }
    echo '</tr>';
}
echo '</table>';

Другие вопросы по теме