我正在重构一个日历应用程序。该日历具有用户定义的网格(可以进行预订的时段),但也需要显示“离网”预订。想想 08:00、09:00 的“常规”时段和 08:39 预订的“不规则”时段。出于业务原因,我需要以不同的方式显示这些插槽(CSS),否则它们的行为相同。我搜索了 PHP 手册,但内置的数组函数并不能完全满足我的需要。
$officialGrid = array(
array('grid' => TRUE, 'time' => '08:00', 'content' => NULL),
array('grid' => TRUE, 'time' => '09:00', 'content' => NULL));
$bookings = array(
array('grid' => NULL, 'time' => '08:00', 'content' => 'Paul Simon'),
array('grid' => NULL, 'time' => '08:00', 'content' => 'Art Garfunkel'),
array('grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'));
我可以只附加这些数组,但出于性能原因希望将结果缩短为:
$timeSlotsToDisplay = array(
array('grid' => TRUE, 'time' => '08:00', 'content' => 'Paul Simon, Art Garfunkel'), //regular
array('grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'), //irregular
array('grid' => TRUE, 'time' => '09:00', 'content' => NULL)); //vacant
我还可以灵活地更改值的数据类型(
content
可能是一个数组)。除了开始循环和比较之外,是否有任何优雅的解决方案来合并这些数组?
PS:只是为了说明,在 PostgreSQL 术语中,我需要
SELECT DISTINCT ON (time) grid, time, string_agg(content) FROM myDB GROUP BY time ORDER BY time, grid;
(请忽略可能的关键字,由于格式原因不引用,也没有测试查询)。
我认为循环没有任何问题..但我建议使用另一种结构
$officialGrid
数组
$officialGrid = array(
'08:00' => array('grid' => TRUE, 'content' => NULL),
'09:00' => array('grid' => TRUE, 'content' => NULL));
$bookings = array(
array('grid' => NULL, 'time' => '08:00', 'content' => 'Paul Simon'),
array('grid' => NULL, 'time' => '08:00', 'content' => 'Art Garfunkel'),
array('grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'));
$timeSlotsToDisplay = $officialGrid;
array_map(function($el) use(&$timeSlotsToDisplay, $officialGrid) {
$timeSlotsToDisplay[$el['time']] = array(
'content' =>
(isset($timeSlotsToDisplay[$el['time']]) ?
trim($timeSlotsToDisplay[$el['time']]['content'], ',') . ',' : '') .
$el['content'],
'grid' => isset($officialGrid[$el['time']]) ? true : null
);
}, $bookings);
ksort($timeSlotsToDisplay);
var_dump($timeSlotsToDisplay);
array_map
可以替换为单个 foreach
循环。
“我查了PHP手册,但内置数组函数没有 完全按照我的需要去做。”
内置数组功能比仅仅循环遍历一堆数组更有效,您应该看看 php 中的 array_merge 和 array_merge_recursive 以获得如何执行此操作的更有效答案,或者按照信息进行操作使用 SQL 从数据库中拉取。
对于一个实用的 php 解决方案,如果您可以循环遍历每个二维数组中的每一行并获取您想要的信息,但这假设 $officialGrid 中每个数组的键的结构与 $bookings 中每个数组的键相同。它应该根据“时间”循环并匹配相同的数据,并跳过预订中不匹配的数据。根据您拥有的信息行数,循环可以很好地与数组一起使用,但它们远非最佳。
$officialGrid = Array(
Array('grid' => TRUE, 'time' => '08:00' // ... arrays assumed to be populated with example data above
$bookings = Array(
Array('grid' => NULL, 'time' => '08:00' // ... arrays assumed to be populated with example data above
// fill final array with content from $bookings
$timeSlotsToDisplay = $bookings;
foreach($officialGrid as $officalkey=>$officalobj) {
foreach($timeSlotsToDisplay as $bookkey=>$obj) {
if(!isset($officialGrid[$officalobj['time']]) || !isset($timeSlotsToDisplay[$bookobj['time']])) {
//one of them is not set.. error
}
//if the times match when looping
if( $officialGrid[$officalobj['time']] == $timeSlotsToDisplay[$bookobj['time']]) {
//keeps the information from officialgrid data for column, and keep $booking data for content column
//the null grid entries will just stay the same, as $bookings oringally had
$timeSlotsToDisplay[$officalobj['grid']];
$timeSlotsToDisplay[$bookobj['time']]
$timeSlotsToDisplay[$bookobj['content']];
}
}
}
$officialGrid
,这将作为结果数组的基础数据。$bookings
数组。$content
列值,然后是新行的 content
值。array_values()
重新索引结果(删除临时键)。代码:(演示)
$result = array_column($officialGrid, null, 'time');
foreach ($bookings as $row) {
if (!isset($result[$row['time']])) {
$result[$row['time']] = $row;
} else {
$result[$row['time']]['content'] = sprintf(
'%s%s',
(isset($result[$row['time']]['content']) ? "{$result[$row['time']]['content']}, " : ''),
$row['content']
);
}
}
ksort($result);
var_export(array_values($result));