I am trying to find the best way on how to merge date ranges into one database record (array element).
This is the data I have:
Array
(
[0] => Array
(
[id] => 18298
[start_date] => 2011-07-09
[end_date] => 2011-10-01
)
[1] => Array
(
[id] => 18297
[start_date] => 2011-06-01
[end_date] => 2011-06-30
)
[2] => Array
(
[id] => 17113
[start_date] => 2011-03-31
[end_date] => 2011-05-31
)
[3] => Array
(
[id] => 20555
[start_date] => 2011-01-03
[end_date] => 2011-03-31
)
)
And after we combine them, array (or database) should look like this:
Array
(
[0] => Array
(
[merged_ids] => 18298
[start_date] => 2011-07-09
[end_date] => 2011-10-01
)
[1] => Array
(
[merged_ids] => 18297, 17113, 20555
[start_date] => 2011-01-03
[end_date] => 2011-06-30
)
)
Is there any algorithm to go through all elements/ranges and combine them? Which way is better/easier to do - through database (MYSQL) or coding (PHP)?
Any advise is highly appreciated.
Thanks!
UPDATE: Sorry, I didn't provide enough info: we should merge any continuous and overlapping date ranges.
Sort by start date.
Then iterate through and check for if the next item's start date is before or directly after the current one's end date. If it is, then merge the next one into the current one. Then continue.
I've written function which combines/merges list of ranges. It is written in Python, but it should be easy to rewrite it in PHP. Here's full code: https://gist.github.com/barszczmm/8447665 and here's simplified algorithm (still in Python):
list_of_ranges.sort() # sort input list
new_list_of_ranges = [] # output list
new_range_item_start = None
new_range_item_end = None
length = len(list_of_ranges)
for i, range_item in enumerate(list_of_ranges):
if new_range_item_start is None:
new_range_item_start = range_item[0]
new_range_item_end = range_item[1]
elif new_range_item_end >= range_item[0]:
new_range_item_end = max(range_item[1], new_range_item_end)
else:
new_list_of_ranges.append((new_range_item_start, new_range_item_end))
new_range_item_start = range_item[0]
new_range_item_end = range_item[1]
# save if this is last item
if i + 1 == length:
new_list_of_ranges.append((new_range_item_start, new_range_item_end))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With