Reputation: 23
I have a date range 2023-11-01 to 2024-01-04 and some date have different MinStay value.
This is my array of date range
$input = [
[ 'date' => '2023-11-01', 'MinStay' => 1 ],
[ 'date' => '2023-11-02', 'MinStay' => 1 ],
[ 'date' => '2023-11-03', 'MinStay' => 1 ],
[ 'date' => '2023-11-04', 'MinStay' => 2 ],
[ 'date' => '2023-11-05', 'MinStay' => 2 ],
[ 'date' => '2023-11-06', 'MinStay' => 2 ],
[ 'date' => '2023-12-10', 'MinStay' => 1 ],
[ 'date' => '2023-12-11', 'MinStay' => 1 ],
[ 'date' => '2023-12-12', 'MinStay' => 3 ],
[ 'date' => '2023-12-13', 'MinStay' => 2 ],
[ 'date' => '2023-12-14', 'MinStay' => 2 ],
[ 'date' => '2024-01-01', 'MinStay' => 4 ],
[ 'date' => '2024-01-02', 'MinStay' => 4 ],
[ 'date' => '2024-01-03', 'MinStay' => 4 ],
[ 'date' => '2024-01-04', 'MinStay' => 4 ],
];
And I want to
$output = [
[ 'dateForm' => '2023-11-01', 'dateTo' => '2023-11-03', 'MinStay' => 1 ],
[ 'dateForm' => '2023-11-04', 'dateTo' => '2023-11-06', 'MinStay' => 2 ],
[ 'dateForm' => '2023-12-10', 'dateTo' => '2023-12-11', 'MinStay' => 1 ],
[ 'dateForm' => '2023-12-12', 'dateTo' => '2023-12-12', 'MinStay' => 3 ],
[ 'dateForm' => '2023-12-13', 'dateTo' => '2023-12-14', 'MinStay' => 2 ],
[ 'dateForm' => '2024-01-01', 'dateTo' => '2024-01-04', 'MinStay' => 4 ],
];
How can I solve this issue.
I'm try using this array but it's not happening.
$arr = [];
foreach ($input as $date) {
if ($date['MinStay'] == 1) {
$arr[] = [
'dateFrom' => $date['date'],
'dateTo' => $date['date'],
'MinStay' => $date['MinStay'],
];
}
}
Upvotes: 0
Views: 67
Reputation: 48031
For maximum elegance, push reference variables into the result array and only update the current reference.
Your input data was insufficiently challenging to expose solutions which do not factor contiguous dates. I've extended the sample input.
$input = [
[ 'date' => '2023-11-01', 'MinStay' => 1 ],
[ 'date' => '2023-11-02', 'MinStay' => 1 ],
[ 'date' => '2023-11-03', 'MinStay' => 1 ],
[ 'date' => '2023-11-04', 'MinStay' => 2 ],
[ 'date' => '2023-11-05', 'MinStay' => 2 ],
[ 'date' => '2023-11-06', 'MinStay' => 2 ],
[ 'date' => '2023-12-10', 'MinStay' => 1 ],
[ 'date' => '2023-12-11', 'MinStay' => 1 ],
[ 'date' => '2023-12-12', 'MinStay' => 3 ],
[ 'date' => '2023-12-13', 'MinStay' => 2 ],
[ 'date' => '2023-12-14', 'MinStay' => 2 ],
[ 'date' => '2023-12-24', 'MinStay' => 2 ], // <-- added challenge where same minstay is not on contiguous date
[ 'date' => '2024-01-01', 'MinStay' => 4 ],
[ 'date' => '2024-01-02', 'MinStay' => 4 ],
[ 'date' => '2024-01-03', 'MinStay' => 4 ],
[ 'date' => '2024-01-04', 'MinStay' => 4 ],
];
Code: (Demo)
$result = [];
$lastMinStay = null;
foreach ($input as ['date' => $d, 'MinStay' => $ms]) {
if ($ms !== $lastMinStay || $d !== date('Y-m-d', strtotime("{$ref['dateTo']} +1 day"))) {
unset($ref);
$ref = ['dateFrom' => $d, 'dateTo' => $d, 'MinStay' => $ms];
$result[] =& $ref;
$lastMinStay = $ms;
continue;
}
$ref['dateTo'] = $d;
}
var_export($result);
Output:
array (
0 =>
array (
'dateFrom' => '2023-11-01',
'dateTo' => '2023-11-03',
'MinStay' => 1,
),
1 =>
array (
'dateFrom' => '2023-11-04',
'dateTo' => '2023-11-06',
'MinStay' => 2,
),
2 =>
array (
'dateFrom' => '2023-12-10',
'dateTo' => '2023-12-11',
'MinStay' => 1,
),
3 =>
array (
'dateFrom' => '2023-12-12',
'dateTo' => '2023-12-12',
'MinStay' => 3,
),
4 =>
array (
'dateFrom' => '2023-12-13',
'dateTo' => '2023-12-14',
'MinStay' => 2,
),
5 =>
array (
'dateFrom' => '2023-12-24',
'dateTo' => '2023-12-24',
'MinStay' => 2,
),
6 =>
array (
'dateFrom' => '2024-01-01',
'dateTo' => '2024-01-04',
'MinStay' => 4,
),
)
Upvotes: 1
Reputation: 54
Firstly, loop through the array, keep track of the current date range, and compare the MinStay
value with the previous one
If they are the same, extend the range, otherwise, push the current range to the output and start a new one.
$input = [
['date' => '2023-11-01', 'MinStay' => 1],
['date' => '2023-11-02', 'MinStay' => 1],
['date' => '2023-11-03', 'MinStay' => 1],
['date' => '2023-11-04', 'MinStay' => 2],
['date' => '2023-11-05', 'MinStay' => 2],
['date' => '2023-11-06', 'MinStay' => 2],
['date' => '2023-12-10', 'MinStay' => 1],
['date' => '2023-12-11', 'MinStay' => 1],
['date' => '2023-12-12', 'MinStay' => 3],
['date' => '2023-12-13', 'MinStay' => 2],
['date' => '2023-12-14', 'MinStay' => 2],
['date' => '2024-01-01', 'MinStay' => 4],
['date' => '2024-01-02', 'MinStay' => 4],
['date' => '2024-01-03', 'MinStay' => 4],
['date' => '2024-01-04', 'MinStay' => 4],
];
$output = [];
$currentRange = null; // Will store the current range of dates
foreach ($input as $date) {
// If currentRange is empty, start a new range
if ($currentRange === null) {
$currentRange = [
'dateForm' => $date['date'],
'dateTo' => $date['date'],
'MinStay' => $date['MinStay'],
];
} else {
// Check if MinStay matches the current range's MinStay
if ($date['MinStay'] === $currentRange['MinStay']) {
// Extend the date range
$currentRange['dateTo'] = $date['date'];
} else {
// If MinStay changes, push the current range to the output
$output[] = $currentRange;
// Start a new range
$currentRange = [
'dateForm' => $date['date'],
'dateTo' => $date['date'],
'MinStay' => $date['MinStay'],
];
}
}
}
// Add the last range to the output
if ($currentRange !== null) {
$output[] = $currentRange;
}
// Output the result
print_r($output);
Upvotes: 0