无法根据2个变量找出usort逻辑

时间:2013-04-25 12:57:06

标签: php usort

我有一系列对象(目标),我想根据其中的两个属性StatusDueDate进行排序。

以下是规则:

以下状态:

  1. 设计
  2. 已批准
  3. 正在进行中
  4. 已完成
  5. 已归档
  6. 如果目标的状态为4(已完成)或5(已存档),则DueDate无关紧要。

    如果一个目标既不是4也不是5而且DueDate小于现在那么它是“过期”并且应该在顶部

    如果目标不是“过期”,那么状态的顺序决定了它的位置(从最低到最高)

    如果$a$b都是“过期”,那么最早DueDate的那个更为重要

    订单应该是:

    1. 逾期
    2. 设计
    3. 已批准
    4. 正在进行中
    5. 已完成
    6. 已归档
    7. 这是我尝试过的最后一件事:

      function cmp($a, $b)
      {
          $now = new DateTime("now");
          $aDueDate = new DateTime($a->GetDueDate());
          $bDueDate = new DateTime($b->GetDueDate());
      
      if($a->GetStatus() != 4 && $a->GetStatus() != 5 && $b->GetStatus() != 4 && $b->GetStatus() != 5){
          if($aDueDate < $now || $bDueDate < $now){
              if($aDueDate == $bDueDate){
              return 0;
          }
      
          return ($aDueDate < $bDueDate) ? -1 : 1;
          }
      }
      elseif(($a->GetStatus() == 4 || $a->GetStatus() == 5) && ($b->GetStatus() != 4 && $b->GetStatus() != 5)) {
          return -1;
      }
      elseif(($a->GetStatus() != 4 && $a->GetStatus() != 5) && ($b->GetStatus() == 4 || $b->GetStatus() == 5)){
          return 1;
      }
      
      if ($a->GetStatus() == $b->GetStatus()) {
              return 0;
          }
          return ($a->GetStatus() < $b->GetStatus()) ? -1 : 1;
      }
      

      对数组的命令是这样的:

      1. 已完成
      2. 已归档
      3. 逾期
      4. 设计
      5. 已批准
      6. 正在进行中

1 个答案:

答案 0 :(得分:1)

以下内容应符合您的要求:

function cmp($a, $b) {
    $now = new DateTime("now");
    $aDueDate = new DateTime($a->GetDueDate());
    $bDueDate = new DateTime($b->GetDueDate());
    $aStatus = $a->GetStatus();
    $bStatus = $b->GetStatus();
    $incompleteStatuses = array(1, 2, 3); 

    // use date if same status (might not be needed)    
    if ($aStatus == $bStatus) {
        return ($aDueDate < $bDueDate ? -1 : 1); 
    }   

    // if A is overdue:
    if (in_array($aStatus, $incompleteStatuses) && $aDueDate < $now) {
        // if B is overdue too, only consider dates
        if (in_array($bStatus, $incompleteStatuses) && $bDueDate < $now) {
            return ($aDueDate < $bDueDate ? -1 : 1); 
        }   

        return -1; // A definitely first
    }   
    // if B is overdue:
    elseif (in_array($bStatus, $incompleteStatuses) && $bDueDate < $now) {
        return 1; // B definitely first (we know A is not overdue from above)
    }   

    // both A and B are not overdue; order by status
    return $aStatus - $bStatus;
}

Here's a test codepad