PHP sort weekday и month-year array по индивидуальному заказу

У меня есть целый ряд рабочих дней (см. Ниже), которые я хотел бы отсортировать как «Mon-Tue-Wed-Thu-Fri-Sat-Sun».

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

Я попробовал следующий код, но он работает некорректно, результатом является упорядоченный массив, вставленный выше, то есть не в том порядке, в котором я бы хотел.

 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"); 

Я также хотел бы сделать аналогичную вещь с массивом месяцев-лет (например, «Июнь 2010» => 10, «Май 2009» => 111 и т. Д.), Но как только я получу это правильно, это будет проще.

Большое спасибо.

Вы можете попробовать это.

 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"); 

или если вы используете php 5.3 или выше, вы можете использовать закрытие;

 $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);}); 

Это позволит избежать воссоздания массива $weekdays с каждой итерацией.

Я бы рекомендовал изменить ключи массива на что-то более читаемое компьютером (и сортировать), поэтому используйте числа в качестве ключа:

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

Затем вы можете сортировать дни:

 ksort($days); 

По крайней мере, для таких сложных клавиш, как «Июнь 2010», сортировать массив практически невозможно. Вы могли бы использовать такие ключи, как $key = year*12+month; иметь отсортированный индекс. «Июнь 2010» можно записать как 24125 (2010 * 12 + 5), если вы используете 0 за январь.

Или используйте отметку времени в первый день месяца:

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

Это более гибко, если вы хотите иметь ежедневный отчет.

Немного поздно для принятия, но одно преимущество заключается в том, что это будет работать со днями других языков, поскольку оно использует обработку даты и времени PHP

 $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; }); 

Для такой простой задачи кажется излишне сложным, я уверен, что есть лучший способ!

Для этого метода требуется 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);