根据多个列值对数组行进行分组和过滤
Group and filter array rows based on multiple column values
我有一组行,其中包含酒店不同日期的空房情况。我需要过滤数组以确定酒店在哪些日期没有空房。
$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"],
]
01-07-2022
只有A
个条目,所以该日期有空缺。
02-07-2022
有 A
和 U
个条目,因此该日期有空缺。
03-07-2022
只有 U
个条目,因此该日期没有空缺。
04-07-2022
只有U
,所以那个日期没有空缺。
预期结果表明日期没有空缺::
[
[
"room_id" => "2",
"date" => "03-07-2022"
"available" => "U"
],
[
"room_id" => "1",
"date" => "04-07-2022"
"available" => "U"
],
]
我试过以下方法:
foreach ($roomsArr as $room) {
if ($room['availability'] === 'U') {
$unavailable[] = $room;
}
else if ($room['availability'] === 'A') {
$available[] = $room;
}
}
foreach ($unavailable as $uv) {
foreach ($available as $av) {
if ($av['date'] === $uv['date']) {
if ($av['availability'] === 'A' && $uv['availability'] === 'A') {
}
else if ($av['availability'] === 'A' && $uv['availability'] === 'U') {
}
else if ($av['availability'] === 'U' && $uv['availability'] === 'U') {
$arr1[] = $av;
}
}
}
}
我会展示两个 approaches/snippets 具有不同的好处。
首先将它们分成空数组和 non-vacant 数组,然后将这两个数组中的数据按日期分组,这样每个日期就不会出现重复条目。
数据分离分组后,只需要比较dates/keys没有空缺的日期和有空缺的日期即可。剩下的就是酒店没有空房的日期。
这可能更容易概念化,但性能不如第二个代码段,因为它执行两个单独的迭代技术。
代码:(Demo)
$hasVacancy = [];
$hasNoVacancy = [];
foreach ($array as $row) {
if ($row['available'] === 'A') {
$hasVacancy[$row['date']] = $row;
} else {
$hasNoVacancy[$row['date']] = $row;
}
}
var_export(
array_values(array_diff_key($hasNoVacancy, $hasVacancy))
);
输出:
array (
0 =>
array (
'room_id' => '2',
'date' => '03-07-2022',
'available' => 'U',
),
1 =>
array (
'room_id' => '1',
'date' => '04-07-2022',
'available' => 'U',
),
)
更高效的是,您需要维护一个查找数组以确保某个日期没有可用房间。如果你能理解其中的逻辑,我推荐这个片段。只需要遍历输入数组一次
代码:(Demo)
$hasVacancy = [];
$result = [];
foreach ($array as $row) {
if ($row['available'] === 'A') {
$hasVacancy[$row['date']] = $row; // store available as reference
unset($result[$row['date']]); // remove potentially stored unavailable row for date
} elseif (!isset($hasVacancy[$row['date']])) {
$result[$row['date']] = $row; // is unavailable and no availables found
}
}
var_export(array_values($result));
// same result as previous snippet
我有一组行,其中包含酒店不同日期的空房情况。我需要过滤数组以确定酒店在哪些日期没有空房。
$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"],
]
01-07-2022
只有A
个条目,所以该日期有空缺。
02-07-2022
有 A
和 U
个条目,因此该日期有空缺。
03-07-2022
只有 U
个条目,因此该日期没有空缺。
04-07-2022
只有U
,所以那个日期没有空缺。
预期结果表明日期没有空缺::
[
[
"room_id" => "2",
"date" => "03-07-2022"
"available" => "U"
],
[
"room_id" => "1",
"date" => "04-07-2022"
"available" => "U"
],
]
我试过以下方法:
foreach ($roomsArr as $room) {
if ($room['availability'] === 'U') {
$unavailable[] = $room;
}
else if ($room['availability'] === 'A') {
$available[] = $room;
}
}
foreach ($unavailable as $uv) {
foreach ($available as $av) {
if ($av['date'] === $uv['date']) {
if ($av['availability'] === 'A' && $uv['availability'] === 'A') {
}
else if ($av['availability'] === 'A' && $uv['availability'] === 'U') {
}
else if ($av['availability'] === 'U' && $uv['availability'] === 'U') {
$arr1[] = $av;
}
}
}
}
我会展示两个 approaches/snippets 具有不同的好处。
首先将它们分成空数组和 non-vacant 数组,然后将这两个数组中的数据按日期分组,这样每个日期就不会出现重复条目。
数据分离分组后,只需要比较dates/keys没有空缺的日期和有空缺的日期即可。剩下的就是酒店没有空房的日期。
这可能更容易概念化,但性能不如第二个代码段,因为它执行两个单独的迭代技术。
代码:(Demo)
$hasVacancy = [];
$hasNoVacancy = [];
foreach ($array as $row) {
if ($row['available'] === 'A') {
$hasVacancy[$row['date']] = $row;
} else {
$hasNoVacancy[$row['date']] = $row;
}
}
var_export(
array_values(array_diff_key($hasNoVacancy, $hasVacancy))
);
输出:
array (
0 =>
array (
'room_id' => '2',
'date' => '03-07-2022',
'available' => 'U',
),
1 =>
array (
'room_id' => '1',
'date' => '04-07-2022',
'available' => 'U',
),
)
更高效的是,您需要维护一个查找数组以确保某个日期没有可用房间。如果你能理解其中的逻辑,我推荐这个片段。只需要遍历输入数组一次
代码:(Demo)
$hasVacancy = [];
$result = [];
foreach ($array as $row) {
if ($row['available'] === 'A') {
$hasVacancy[$row['date']] = $row; // store available as reference
unset($result[$row['date']]); // remove potentially stored unavailable row for date
} elseif (!isset($hasVacancy[$row['date']])) {
$result[$row['date']] = $row; // is unavailable and no availables found
}
}
var_export(array_values($result));
// same result as previous snippet