2017-08-07 46 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我添加了所有规则组合的解决方案,并考虑了当前正在进行的事件。 –