Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array of weekdays (see below) that I would like to sort as "Mon-Tue-Wed-Thu-Fri-Sat-Sun".

"Sun"=>59
"Sat"=>41
"Fri"=>21
"Thu"=>11
"Wed"=>14
"Tue"=>19
"Mon"=>31

I tried the following code but it doesn't seem to work correctly, the result being the ordered array pasted above, i.e. not in the order I would like it to be.

function orderbyweekday($a, $b) {

    if (strcmp($a, "Mon") == 0) 
        $a = 0;
    else if (strcmp($a, "Tue") == 0) 
        $a = 1;    
    else if (strcmp($a, "Wed") == 0) 
        $a = 2;
    else if (strcmp($a, "Thu") == 0) 
        $a = 3; 
    else if (strcmp($a, "Fri") == 0) 
        $a = 4;
    else if (strcmp($a, "Sat") == 0)  
        $a = 5;
    else if (strcmp($a, "Sun") == 0)   
        $a = 6;    

    if (strcmp($b, "Mon") == 0) 
        $b = 0;
    else if (strcmp($b, "Tue") == 0) 
        $b = 1;    
    else if (strcmp($b, "Wed") == 0) 
        $b = 2;
    else if (strcmp($b, "Thu") == 0) 
        $b = 3; 
    else if (strcmp($b, "Fri") == 0) 
        $b = 4;
    else if (strcmp($b, "Sat") == 0)  
        $b = 5;
    else if (strcmp($b, "Sun") == 0)   
        $b = 6;    

    // if same day, return 0
    if ($a == $b) {
        return 0;
    } 

    return ($a > $b) ? -1 : 1;
}

uksort($movies_per_day, "orderbyweekday");

I would also like to do a similar thing with an array of month-years (e.g. "June 2010"=>10, "May 2009"=>111, etc.), but once I get this right it should be easier.

Thanks a lot.

share|improve this question
add comment

4 Answers

up vote 0 down vote accepted

You can try this.

function weekdaySort($a, $b){
      $weekdays = array("Mon", "Tue","Wed","Thu","Fri", "Sat", "Sun");
      return array_search($a, $weekdays) - array_search($b, $weekdays);
} 

uksort($movies_per_day, "weekdaySort");

or if you are using php 5.3 or above you can use a closure;

$weekdays = array("Mon", "Tue","Wed","Thu","Fri", "Sat", "Sun");
uksort($movies_per_day, function($a, $b) use ($weekdays) {return array_search($a, $weekdays) - array_search($b, $weekdays);});

This will avoid recreating the $weekdays array with each iteration.

share|improve this answer
 
Great, it works! Still I don't understand what I did wrong, but nevermind. Thanks! –  MDT Jul 16 '13 at 13:56
 
I think the original error would have been resolved by changing return ($a > $b) ? -1 : 1; to return ($a < $b) ? -1 : 1; –  Orangepill Jul 16 '13 at 13:58
 
Feel free to accept the answer if this worked out for you. –  Orangepill Jul 16 '13 at 14:00
 
Thank you very much! –  MDT Jul 16 '13 at 14:04
add comment

I would recommend to change the array keys to something more computer readable (and sortable), so use numbers as key:

$days = array(6=>59,5=>41,4=>21,3=>11,2=>14,1=>19,0=>31);

You then are able to sort the days by:

ksort($days);

At least for such difficult keys as "June 2010" it is nearly impossible to sort your array. You could use keys like $key = year*12+month;to have a sortable index. "June 2010" could be written as 24125 (2010*12+5), if you use 0 for January.

Or use a timestamp of the first day of a month:

$key = mktime(0,0,0,6,1,2010);

This is more flexible if you want to have a daily report some day.

share|improve this answer
add comment

A little late for the accept, but one advantage is that this will work with days of other languages as it uses PHP's date/time handling

$days = array(
    "Sun"=>59,
    "Sat"=>41,
    "Fri"=>21,
    "Thu"=>11,
    "Wed"=>14,
    "Tue"=>19,
    "Mon"=>31,
);
uksort($days, function($a, $b) {

    $c = date_diff(new DateTime('@' . strtotime($a, strtotime('Mon', 0))), new DateTime('@' . strtotime($b, strtotime('Mon', 0))));

    return $c->invert ? 1 : -1;
});

It seems unnecessarily complex for such a simple task, I'm sure there's a better way!

share|improve this answer
add comment

This method requires PHP > 5.3:

$arr = array("Sun"=>59, "Thu"=>11, "Sat"=>41, "Fri"=>21, "Tue"=>19, "Wed"=>14, "Mon"=>31);
$ord = array_flip(array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'));
uksort($arr, function ($a, $b) use($ord){
    return $ord[$a] - $ord[$b];
});
var_dump($arr);
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.