2017-08-07 90 views
0

我正在構建事件列表日曆。事件具有開始日期和結束日期,日期以YYYYMMDD格式存儲。活動列表按天查看,活動可以在一天內完成,也可以在多天內完成。按兩個日期和規則對數組排序

活動當前存儲在一個數組,start_dateend_date

我怎樣才能:

  • 此舉在當前日期到 陣列的頂部開始的任何事件。
  • 然後按開始日期
  • 對事件排序然後通過結束日期

有事件排序看到這個question,但徘徊如何建立起來的邏輯之上。

+0

你想三種類型的排序或在一個所有這些規則? –

回答

2

將當前日期開始的所有事件移動到數組的頂部,但保留其他人按原樣排列!

$today = date('Ymd',strtotime('today')); 
usort($events,function($a,$b) use($today){ 
    if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
    else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    else {return strnatcmp($a['start_date'],$b['start_date']);} 
}); 

排序事件由起始日期

usort($events,function($a,$b){ 
    return strnatcmp($a['start_date'],$b['start_date']); 
}); 

通過結束日期的事件排序

usort($events,function($a,$b){ 
    return strnatcmp($a['end_date'],$b['end_date']); 
}); 

編輯一些測試數據:

//example works best if today is 20170810 
$events = array(
    array(
    'name' => 'a', 
    'start_date' => '20170810', 
    'end_date' => '20170811', 
), 
    array(
    'name' => 'b', 
    'start_date' => '20170810', 
    'end_date' => '20170810', 
), 
    array(
    'name' => 'c', 
    'start_date' => '20170607', 
    'end_date' => '20170608', 
), 
    array(
    'name' => 'd', 
    'start_date' => '20170607', 
    'end_date' => '20170607', 
), 
    array(
    'name' => 'e', 
    'start_date' => '20170810', 
    'end_date' => '20170812', 
), 
    array(
    'name' => 'f', 
    'start_date' => '20170807', 
    'end_date' => '20170817', 
), 
); 
print_r($events); 

編輯:他們都在一起:持續事件是由「被下令:事件是由 '嗎?他們從今天開始', '起始日期', 'END_DATE'

$today = date('Ymd',strtotime('today')); 
usort($events,function($a,$b) use($today){ 
    //one of them starts today 
    if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
    else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    //both or neither start today, compare start_date 
    else { 
    if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    } 
}); 

print_r($events); 

編輯命令?他們目前正在進行中「‘起始日期’,‘END_DATE’

$today = date('Ymd',strtotime('today')); 
//function compares two elements to decide their position relative to each other 
usort($events,function($a,$b) use($today){ 
    //check if event is currently ongoing 
    //starts or ends today or today is between start and end 
    $ongoing = function($event) use($today){ 
    //this is the simplest form I could think of for the check 
    return (strnatcmp($event['start_date'],$today) < 1 && strnatcmp($today,$event['end_date']) < 1); 
    }; 
    $startstoday = function($event) use($today){ 
    return $event['start_date'] === $today; 
    }; 
    //only one of them is ongoing 
    if($ongoing($a) && !$ongoing($b)){return -1;} 
    else if($ongoing($b) && !$ongoing($a)){return 1;} 
    //both or neither are ongoing, compare start_date 
    else { 
    if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    } 
}); 

print_r($events); 

編輯:從今天開始和持續事件被下令‘嗎?他們從今天開始’,」被?他們目前正在進行中」,‘起始日期’,‘END_DATE’

$today = date('Ymd',strtotime('today')); 
//function compares two elements to decide their position relative to each other 
usort($events,function($a,$b) use($today){ 
    //check if event is currently ongoing 
    //starts or ends today or today is between start and end 
    $ongoing = function($event) use($today){ 
    //this is the simplest form I could think of for the check 
    return (strnatcmp($event['start_date'],$today) < 1 && strnatcmp($today,$event['end_date']) < 1); 
    }; 
    //only one of them is ongoing 
    if($ongoing($a) && !$ongoing($b)){return -1;} 
    else if($ongoing($b) && !$ongoing($a)){return 1;} 
    //both are ongoing 
    else if($ongoing($a) && $ongoing($b)){ 
    //one starts today 
    if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
    else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    //both start today 
    else if($a['start_date'] === $today && $b['start_date'] === $today){ 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    //none starts today 
    else { 
     if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
     } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
     } 
    } 
    } else { 
    //neither are ongoing, compare start_date 
    if($a['start_date'] != $b['start_date']){ 
     //start_dates differ, order by them 
     return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
     //start dates are the same, order by end_date 
     return strnatcmp($a['end_date'],$b['end_date']); 
    } 
    } 
}); 

print_r($events); 

和最後一項可以簡化爲:

$today = date('Ymd',strtotime('today')); 
usort($events,function($a,$b) use($today){ 
    $ongoing = function($event) use($today){ 
    return (strnatcmp($event['start_date'],$today) < 1 && strnatcmp($today,$event['end_date']) < 1); 
    }; 
    if($ongoing($a)){ 
    if(!$ongoing($b)){return -1;} 
    else { 
     if($a['start_date'] === $today && $b['start_date'] != $today){return -1;} 
     else if($b['start_date'] === $today && $a['start_date'] != $today){return 1;} 
    } 
    } else if($ongoing($b)){return 1;} 
    if($a['start_date'] != $b['start_date']){ 
    return strnatcmp($a['start_date'],$b['start_date']); 
    } else { 
    return strnatcmp($a['end_date'],$b['end_date']); 
    } 
}); 

print_r($events); 
+0

感謝彼得,是有道理的 - 沒有想到只是彼此適用每一種。 – addedlovely

+1

@addedlovely請記住,每次排序都會撤銷之前的任何排序。您是否希望只有一個分揀機,這三個規則按降序排列? –

+1

@addedlovely我添加了所有規則組合的解決方案,並考慮了當前正在進行的事件。 –