基于多列值分组筛选数组行:识别酒店无空房日期的技术实现问询
Hey, let's work through this problem step by step. Your goal is to identify dates where all hotel rooms are unavailable (marked 'U'), then collect records for those dates. Here's a clear, efficient way to do this, plus a breakdown of where your original code went wrong.
Problem Recap
You have an array of room availability records, and you need to filter out dates where every room is unavailable. For context:
- 03-07-2022: All rooms are 'U' → include this date's records
- 04-07-2022: All rooms are 'U' → include this date's records
- Dates with even one 'A' (available) room should be excluded
Correct Implementation
The core idea is to first group records by date, then check each date group for any available rooms. Here's a working PHP solution:
<?php $array = [ ["room_id" => "1", "date" => "01-07-2022", "available" => "A"], ["room_id" => "2", "date" => "01-07-2022", "available" => "A"], ["room_id" => "1", "date" => "02-07-2022", "available" => "A"], ["room_id" => "2", "date" => "02-07-2022", "available" => "U"], ["room_id" => "1", "date" => "03-07-2022", "available" => "U"], ["room_id" => "2", "date" => "03-07-2022", "available" => "U"], ["room_id" => "1", "date" => "04-07-2022", "available" => "U"], ]; // Step 1: Group records by date and track if any room is available $groupedByDate = []; foreach ($array as $room) { $date = $room['date']; if (!isset($groupedByDate[$date])) { $groupedByDate[$date] = [ 'records' => [], 'has_available' => false ]; } $groupedByDate[$date]['records'][] = $room; // Mark the date as having available rooms if any room is 'A' if ($room['available'] === 'A') { $groupedByDate[$date]['has_available'] = true; } } // Step 2: Filter dates with no available rooms $noAvailableDates = []; foreach ($groupedByDate as $dateData) { if (!$dateData['has_available']) { // Option 1: Collect ALL records for the date (if you want every 'U' entry) // $noAvailableDates = array_merge($noAvailableDates, $dateData['records']); // Option 2: Collect ONE record per date (matches your expected output) $noAvailableDates[] = $dateData['records'][0]; } } // Print the result print_r($noAvailableDates); ?>
Output (with Option 2)
This will match your expected result:
Array ( [0] => Array ( [room_id] => 1 [date] => 03-07-2022 [available] => U ) [1] => Array ( [room_id] => 1 [date] => 04-07-2022 [available] => U ) )
Why Your Original Code Failed
Your initial approach separated available and unavailable records, then tried to compare them with nested loops. This missed the key requirement: you need to evaluate availability per date, not per individual room. The nested loops created confusing logic that couldn't correctly determine if a date had any available rooms at all.
Key Takeaways
- Grouping by date simplifies checking availability for entire days.
- Tracking a
has_availableflag lets you quickly filter out dates with no empty rooms. - Choose between collecting all records for a date or just one, depending on your needs.
内容的提问来源于stack exchange,提问作者newbie_dev

