我有一个多维数组,如下所示。我想在表格中显示数据,将一周中的每一天及其开始和结束时间显示在一行中。下表附有预期结果。
我对数组不熟悉,所以我还没有真正尝试过任何值得一提的东西。
$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" => []
]
];
你可以这样做。请阅读代码中的注释以及输出下面的注释。
<?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>',
implode(
' to ',
[
...(array) ($opens[$i] ?? []),
...(array) ($times['closing_time'][$day][$i] ?? [])
]
)
);
}
echo '</tr>';
}
echo '</table>';