2012-07-16 77 views
7

我有以下陣列:排序工作日名稱的數組

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

     ) 

) 

我想這個數組與第一個關鍵是明天一天的元素進行排序。假設今天是星期三。我想我的陣列看起來像這樣:

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

     ) 
) 

我已經有星期幾可用(例如字符串'星期四')。它被傳遞到我正在使用的函數中。

有關實現此類排序的任何建議?謝謝!

回答

4

如果將日期轉換爲數字0-6,您可以多次將array_shiftarray_push轉換爲數組的末尾。

+0

你們對我的情況下,最簡單的解決方案。如果你能告訴我如何得到一天,作爲'當前明天'的一個數字(0-6) – kwikness 2012-07-16 17:22:25

+0

對不起,遲到的答覆...'日期('N')%7'會爲你做那個。 N返回一個數字1-7,所以'date('N')%7'將成爲我們0-6號碼的第二天。 – 2012-07-20 02:59:13

3

嘗試使用uksort()。您可以比較鏈接中描述的回調函數中的日期。

例如:

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

uksort($array, "compare"); 

這裏的proof of it working

+0

它是如何考慮OP的「限制排列這個數組的元素,第一個鍵是明天的[星期]日」? – nickb 2012-07-16 02:48:10

+1

我在下面使用的代碼也是uksort,但只需稍作調整以滿足'從今天開始...'的要求。 – Fluffeh 2012-07-16 03:52:25

+0

@Martin,你不需要在'compare'函數中使用'return'嗎?另外,爲什麼你不能只使用'strtotime($ a) - strtotime($ b)'? – parrker9 2016-03-07 07:31:36

1

首先,你需要以正確的順序,您可以通過DateTime類搶列表。然後,你遍歷舊的陣列,使用正確的順序爲重點,以對數組進行排序,像這樣:

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

你可以看到它在the demo工作。

3

您可以通過date函數獲取星期幾。星期日是0,星期一是1,等等。

$weekday = date("w"); 

然後,我建議使用uksort函數到所述陣列相對於它的鍵,這需要一個回調函數作爲排序準則排序。

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

我寫了一個解決方案,它不會將日期轉換爲日期/時間類型,而是使用閉包和uksort。基本上,傳遞給uksort的每個密鑰都與「明天」密鑰的位置進行比較,如果明天是「之前」,則將「提升」到未來(+= 7),然後使用簡單的比較結果。

編輯的性能:(!謝謝)

編輯由@nickb通過評論的動機

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

性能指出

我使用10萬次迭代測試,這種方法花費大約2.2E-5秒排序數組。好奇的人會檢查這個答案的第一個版本,以找到一個性能較低的版本,花費兩倍長,5.5e-5秒。

+1

由於'array_search'是O(n),並且您在回調中重複調用'array_search'和'array_keys'以進行排序,所以這可能不是非常有效。 – nickb 2012-07-16 02:49:35

+0

這是一個相當簡單的重構(至少其中一個......) – 2012-07-16 03:22:14

+0

並且在另一個小重構中,所有重函數已從閉包中移除;感謝您的輸入,@nickb :-) – 2012-07-16 03:39:47

1

如果您將uksort與簡單的功能相結合,這是一個非常簡單的解決方案。

很明顯,將日期名稱字符串轉換爲整數是必要的,但是如果日期早於當前工作日,只需將7添加到變量中,即可保證數組按照'after'排序,即使否則這一週將意味着。

<?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") 
?> 
0

這是爲我工作,只是一個簡單的循環:

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

輸出數組看起來像:(如果今天是星期二)

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

此解答允許其日本週開始,並動態處理日子如何標記。

這只是一個改進的解決方案,使用uksort(),date()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); 
} 

排序鍵與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); 

排序鍵與usort()

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