Rotate an array with weekday names as keys to start with tomorrow

11,862

Solution 1

If you convert the day to a number 0-6 you can array_shift and array_push that many times to move the previous days to the end of the array.

Solution 2

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's proof of it working

Solution 3

You can get the day of the week via the date function. Sunday is 0, Monday is 1, and so forth.

$weekday = date("w");

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

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

Solution 4

you can do like this to achieve this

$week = [
    'sunday',
    'monday',
    'tuesday',
    'wednesday',
    'thursday',
    'friday',
    'saturday',
];

  $day = date('w'); // weekday as integer(3 for Wednesday)

  for ($i=0; $i <= $day ; $i++) {
    array_push($week, array_shift($week));
  }

  $result = $week;

Result (if today is Wednesday):

    Array
    (
        [0] => thursday
        [1] => friday
        [2] => saturday
        [3] => sunday
        [4] => monday
        [5] => tuesday
        [6] => wednesday
    )

Solution 5

First you need a list in the correct order, which you can grab through the DateTime class. Then, as you loop over the old array, use the correct order as the key to sort the array, like so:

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 it working in the demo.

Share:
11,862

Related videos on Youtube

kwikness
Author by

kwikness

Updated on September 14, 2022

Comments

  • kwikness
    kwikness over 1 year

    I have the following array:

    [
         [
             'schedules' => [
                 'monday' => 1,
                 'tuesday' => 1,
                 'wednesday' => 1,
                 'thursday' => 1,
                 'friday' => 1,
                 'saturday' => 0,
                 'sunday' => 1,
             ]
        ]
    ]
    

    I'd like to rotate the elements of this array with the first key being the tomorrow. Let's say today was Wednesday, I'd want my array to look like this:

    [
         [
             'schedules' => [
                 'thursday' => 1,
                 'friday' => 1,
                 'saturday' => 0,
                 'sunday' => 1,
                 'monday' => 1,
                 'tuesday' => 1,
                 'wednesday' => 1,
             ]
        ]
    ]
    

    I already have the weekday available (e.g. a string 'thursday'). It gets passed into the function that I'm working with.

  • nickb
    nickb almost 12 years
    How does it take into account the OPs restriction of "sort the elements of this array with the first key being the [week]day [of] tomorrow"?
  • nickb
    nickb almost 12 years
    Since array_search is O(n) and you're repeatedly calling both array_search and array_keys in a callback for sorting, this is likely not very efficient at all.
  • Chris Trahey
    Chris Trahey almost 12 years
    That's a fairly easy refactor (at lease one of them...)
  • Chris Trahey
    Chris Trahey almost 12 years
    And with another small refactor, all heavy functions have been removed from the closure; thanks for the input, @nickb :-)
  • Fluffeh
    Fluffeh almost 12 years
    The code I used below is also a uksort, but with a small tweak to cater for the 'sort from today onwards...' request.
  • kwikness
    kwikness almost 12 years
    you have the simplest solution for my case. best answer goes to you if you can tell me how to get the day, as a number (0-6) of the 'current tomorrow'
  • Adam Bergmark
    Adam Bergmark almost 12 years
    Sorry for the late reply... date('N')%7 will do that for you. N returns a number 1-7, so date('N')%7 will be the the next day in our 0-6 numbering.
  • parrker9
    parrker9 about 8 years
    @Martin, don't you need to use return in the compare function? Also, why can't you just use strtotime($a) - strtotime($b)?
  • booota
    booota about 6 years
    Hi Chris, your answer helped me alot in a plugin that i was writing. However, i am getting a warning PHP Warning: array_combine(): Both parameters should have an equal number of elements. Can you tell me why is it so. I have checked the size of both arrays and they are 7.
  • mickmackusa
    mickmackusa almost 3 years
    There is NO WAY that this works. This is 100% teaching researchers to code incorrectly. Why are there upvotes on this answer? Even if did work, it is even ignoreing the OP's requirements!
  • mickmackusa
    mickmackusa almost 3 years
    I don't understand this incomplete answer. I can't see how uksort is an ideal technique here.
  • mickmackusa
    mickmackusa almost 3 years
    This does not represent the OP's input data.
  • mickmackusa
    mickmackusa almost 3 years
    This unexplained answer does not represent the OP's challenge.