Sorting an array of weekday names

I have the following array:

( [0] => Array ( [schedules] => Array ( [monday] => 1 [tuesday] => 1 [wednesday] => 1 [thursday] => 1 [friday] => 1 [saturday] => 0 [sunday] => 1 ) ) ) 

I would like to sort the elements of this array, the first key is the day tomorrow. Let's say today was Wednesday. I would like my array to look like this:

  ( [0] => Array ( [schedules] => Array ( [thursday] => 1 [friday] => 1 [saturday] => 0 [sunday] => 1 [monday] => 1 [tuesday] => 1 [wednesday] => 1 ) ) ) 

I already have an available day of the week (for example, the string "Thursday"). It goes into the function I'm working with.

Any suggestions for achieving this type of sorting? Thanks!

+7
source share
8 answers

If you convert the day to the number 0-6, you can array_shift and array_push repeatedly move the previous days to the end of the array.

+4
source

Try using uksort() . You can compare dates in the callback function described in the link.

For example:

 function compare($a, $b) { date(strtotime($a)) - date(strtotime($b)); } uksort($array, "compare"); 

Here is the proof of his work.

+3
source

You can get the day of the week using the date function. Sunday - 0, Monday - 1, etc.

 $weekday = date("w"); 

Then I suggest using the uksort function to sort the array relative to its keys, which acts as a callback as a sorting guide.

 uksort($schedules, function ($a, $b) use ($weekday) { // convert each day to a number 0-6 and compare to $weekday }); 
+3
source

First you need a list in the correct order, which you can grab through the DateTime class. Then, when you iterate over the old array, use the correct order as the key to sort the array, for example:

 function sort_by_weekday( $input_array) { $now = new DateTime( "tomorrow", new DateTimeZone('America/New_York')); $interval = new DateInterval( 'P1D'); // 1 Day interval $period = new DatePeriod( $now, $interval, 7); // 7 Days $sorted_array = array(); foreach( $period as $day) { $weekday = strtolower( $day->format( 'l')); foreach( $input_array as $key => $value) { $sorted_array[ $key ][ $weekday ] = $value[ $weekday ]; } } return $sorted_array; } 

You can see how it works in the demo .

+1
source

If you combine uksort with a simple function, this is an amazingly simple solution.

Obviously, you need to change the day name strings in ints, but if the day precedes the current weekday, just add seven to the variable, which ensures that the array will be sorted as "after", even if the day the week means otherwise.

 <?php $a='sunday'; // Example Input $b='saturday'; // Example Input function funnyDateCompare($a, $b) { $a=date('w',strtotime($a)); $b=date('w',strtotime($b)); if($a<=date('w')) { $a+=7; // First value is less than or equal to today. // Adding 7 to the answer. } return ($a - $b); } uksort($array, "funnyDateCompare") ?> 
+1
source

I wrote a solution that does not drop days to a date / time type, but uses closure and uksort instead. Essentially, every key passed to uksort is compared with the position of tomorrow, and if it is before tomorrow, it is β€œmoving” into the future ( += 7 ), then a simple comparison result is used.

edited for performance:

Edited by @nickb comment (thanks!)

 <?php function sortedWithNext($days, $tomorrow) { $index_dictionary = array_combine(array_keys($days), range(0,6)); $index_of_tomorrow = $index_dictionary[$tomorrow]; $compare_function = function($k1, $k2) use ($index_dictionary, $index_of_tomorrow) { $index_of_k1 = $index_dictionary[$k1]; $index_of_k2 = $index_dictionary[$k2]; if($index_of_k1 < $index_of_tomorrow) $index_of_k1 += 7; if($index_of_k2 < $index_of_tomorrow) $index_of_k2 += 7; return $index_of_k1 - $index_of_k2; }; uksort($days, $compare_function); return $days; } $daysPool = array( 'monday'=>1, 'tuesday'=>1, 'wednesday'=>1, 'thursday'=>1, 'friday'=>0, 'saturday'=>1, 'sunday'=>1, ); $tomorrow = 'thursday'; $sortedDays = sortedWithNext($daysPool, $tomorrow); var_dump($sortedDays); 

performance notes

I tested using 100,000 iterations, this method takes about 2.2e-5 seconds to sort the array. The curious will check the first version of this answer to find a less effective version that took about twice as long, 5.5 and 5 seconds.

0
source

This works for me, just a simple loop:

 $array = array(); $month = date('m'); $day = date('d'); $year = date('Y'); for($i=1; $i<=7; $i++){ $array[] = date('l',mktime(0,0,0,$month,($day+$i),$year)); } 

The output array looks like this: (If today is Tuesday)

 array( (int) 0 => 'Wednesday', (int) 1 => 'Thursday', (int) 2 => 'Friday', (int) 3 => 'Saturday', (int) 4 => 'Sunday', (int) 5 => 'Monday', (int) 6 => 'Tuesday' ) 
0
source

This answer allows you to start the Day of the week and dynamically process how the days are marked.

This is just an improved solution using uksort () , date () and strtotime () .

 function sort_days( $term1, $term2 ) { $weekdays = array( 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ); foreach ( $weekdays as $key => $value ) { $weekdays[ $key ] = date( 'N', strtotime( $value ) ); } $term1_time = date( 'N', strtotime( strtolower( $term1 ) ) ); $term2_time = date( 'N', strtotime( strtolower( $term2 ) ) ); return array_search( $term1_time, $weekdays ) - array_search( $term2_time, $weekdays ); } 

Sort keys using uksort ()

 $uk_days = array( 'thursday' => 1, 'monday' => 1, 'saturday' => 1, 'wednesday' => 1, 'sunday' => 1, 'friday' => 1, 'tuesday' => 1, ); uksort($uk_days, "sort_days"); var_dump($uk_days); 

Sort keys using usort ()

 $u_days = array( 'thursday', 'monday', 'saturday', 'wednesday', 'sunday', 'friday', 'tuesday', ); usort($u_days, "sort_days"); var_dump($u_days); 
0
source

All Articles