I am refactoring a calendar app. The calendar has a user-defined grid (slots where bookings can occur), but needs to display "off-the-grid" bookings as well. Think of "regular" slots at 08:00, 09:00 and "irregular" slots when someone is booked at 08:39. For business reasons, I need to display these slots differently (CSS), otherwise they behave the same. I've searched the PHP Manual, but the built-in array functions don't do exactly what I need.
$officialGrid = [
['grid' => TRUE, 'time' => '08:00', 'content' => NULL],
['grid' => TRUE, 'time' => '09:00', 'content' => NULL],
];
$bookings = [
['grid' => NULL, 'time' => '08:00', 'content' => 'Paul Simon'],
['grid' => NULL, 'time' => '08:00', 'content' => 'Art Garfunkel'],
['grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'],
];
I could just append these arrays, but for performance reasons would like shorten the result to:
$timeSlotsToDisplay = [
['grid' => TRUE, 'time' => '08:00', 'content' => 'Paul Simon, Art Garfunkel'], //regular
['grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'], //irregular
['grid' => TRUE, 'time' => '09:00', 'content' => NULL], //vacant
];
I'm also flexible to change data types for the values (content
might be an array). Is there any elegant solution for merging these arrays, other than start looping and comparing?
PS: Just to illustrate, in PostgreSQL terms, I need to SELECT DISTINCT ON (time) grid, time, string_agg(content) FROM myDB GROUP BY time ORDER BY time, grid;
(please ignore possible keywords, not quoting due to formatting, also haven't tested the query).
I see nothing wrong with the loops.. but I suggest another structure for the $officialGrid
array
$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
can be replaced by a single foreach
loop.