I have an array with more than 2000 elements like this:
Array
(
[0] => Array
(
[name] => LILI
[actual_start] => 2021-11-10T18:34:00+00:00
[actual_end] => 2021-11-10T21:32:00+00:00
)
[1] => Array
(
[name] => MILI
[actual_start] => 2021-11-18T17:33:00+00:00
[actual_end] => 2022-03-18T19:36:00+00:00
)
.
.
.
)
My goal is to find the TOP 3 elements (their names) based on the duration from actual_start and actual_end.
First, I wanted to convert the difference of actual_start and actual_end to some number and then use that get the top 3 longest. I tried this:
foreach ($array as $data) {
$date1 = new DateTime($data['actual_start']);
$date2 = new DateTime($data['actual_end']);
$interval = $date1->diff($date2);
echo "difference " . $interval->y ;
}
This works but it will give me the difference in years or minutes or hours (if I change y to h or m), but using this value I cannot calculate top 3, any ideas?
4
Answers
You can use a user defined function to tell usort that you want your array sorted by the timespans, something like:
I’d probably sort the whole thing and grab the top three records for this.
Something like:
disclaimer: typed in the SO textbook, haven’t touched php since version 5.4 was the hot new thing.
So, just keep 3 numbers, each for max, 2nd max and 3rd max, thereby constituting your top 3.
Take the difference of
actual_end
andactual_start
for each array usingstrtotime
(although there are many ways to get a diff).Keep comparing with those max variables and keep assigning and re-assigning them values. This would make it efficient in terms of time to retrieve the answer in just a single pass.
Snippet:
Online Fiddle
I fully endorse the efficiency of @nice_dev’s linear solution. Here is an altered version which is easier to adjust — only the
$size
variable needs to be adjusted for larger/smaller filtered sets instead of hardcoding so many individual variables.The
unset()
calls are safe to make even when the targeted element doesn’t exist and serve to ensure that the temporary and result arrays never grow beyond the declared limit.Code: (Demo)
A direct, functional approach with slightly worse time complexity is to sort the entire array, then slice off the row data that you desire.
Code: (Demo)