按两个日期和规则对数组进行排序

时间:2017-08-07 12:49:09

标签: php arrays sorting usort

我正在制作活动列表日历。事件具有开始日期和结束日期,日期以YYYYMMDD格式存储。事件列表按日查看,事件可以是一天,也可以是多天。

事件当前存储在数组中,start_dateend_date

我怎么能:

  • 将当前日期开始的所有事件移至顶部 阵列。
  • 然后按开始日期对事件进行排序
  • 然后按结束日期对事件进行排序

看到这个question,但是我可以徘徊如何构建上面的逻辑。

1 个答案:

答案 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);

编辑:所有这些都在一起:活动是按照'它们今天开始排序的?',' start_date',' end_date&# 39;

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

编辑:正在进行事件按照'目前正在进行排序?',' start_date',' 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);

编辑:今天开始和正在开始事件是按照&#39;今天是否开始?&#39;,&#39;它们目前正在进行中吗?&#39;,&# 39; start_date&#39;,&#39; end_date&#39;

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