1

時間をマージする最良の方法を見つけようとしています...ユーザーが2つのことを行うスケジュールに取り組んでいます:

X 日間の空き状況と割り当てられた時間。

構造はどちらも同じで、次のようになります。

特定の日付については、(2012-10-07) 可用性を言ってみましょう:

[2012-10-07]
             [0][start_time] => 08:30
                [end_time]   => 13:30

             [1][start_time] => 16:30
                [end_time]   => 23:30

その特定の日に、彼が割り当てられ、クエリの結果は次のようになります。

 [2012-10-07][0][start_time] => 08:30
                [end_time]   => 09:30

             [1][start_time] => 10:30
                [end_time]   => 11:30

             [2][start_time] => 17:00
                [end_time]   => 18:30

マージの結果は次のようになります。

 [2012-10-07] [0][start_time]=> 08:30
                 [start_time]=> 09:30
                 [assigned]=> true

              [1][start_time]=> 09:30
                 [start_time]=> 10:30
                 [assigned]=> false

              [2][start_time]=> 10:30
                 [start_time]=> 11:30
                 [assigned]=> true

              [3][start_time]=> 11:30
                 [start_time]=> 13:30
                 [assigned]=> false

              [4][start_time]=> 16:30
                 [start_time]=> 17:00
                 [assigned]=> false

              [5][start_time]=> 16:30
                 [start_time]=> 17:00
                 [assigned]=> false

              [6][start_time]=> 17:00
                 [start_time]=> 18:30
                 [assigned]=> true

              [7][start_time]=> 18:30
                 [start_time]=> 23:30
                 [assigned]=> false

カレンダーで両方を結合すると、空室状況は緑 (false) で、赤 (割り当て済み = true) で割り当てられます。

私がしたことは、可用性をループし、開始/終了時刻を UNIX タイムスタンプに変換してから、割り当てられた時刻ごとにループし、UNIX タイムスタンプに変換することでした。

次に、時間が可用性の範囲内にある場合、またはその範囲外にある場合はすべてのケースをテストし、一時配列を追加して、最終的な配列に変更を加えずにループします。

(新しい時間を生成するたびに、割り当てられた時間に再度ループする必要があるため)

それは機能しますが、私がやっている方法が好きではありません...もっと良い方法はありますか?

アップデート :

ここで完全な作業コードを見たい人のために、それは次のとおりです:

function removeSessionsFromSchedule($schedule,$remove){

    $modified = false;

    if(is_array($schedule) && count($schedule) > 0 && is_array($remove)  && count($remove) > 1) {

       if($modified) {
                break;
            }

       $pos = 0;
            $countdispo = count($dispo); 

        foreach($schedule as $s => $dispo) {
            $pos = 0;
            $countdispo = count($dispo);
            foreach($dispo as  $d) {
                $abs = $remove[$s];
                $counter = 0;
                // dispo debut/end
                $dis_s = strtotime($d['heure_debut']);
                $dis_e = strtotime($d['heure_fin']);
                if(is_array($abs) && count($abs) > 0) {
                    foreach($abs as $a) {
                        // absence start/end
                        $abs_s = strtotime($a['heure_debut']);
                        $abs_e = strtotime($a['heure_fin']);
                        // (2) [a_s]---[ds - de]---[a_e]
                        if($abs_s <= $dis_s && $abs_e >= $dis_e) {
                            // delete availabilities
                            unset($schedule[$s][$pos]); 
                            $modified = false;
                        }
                        // (7)[as == ds] && [ae < de]
                        else if($abs_s == $dis_s && $abs_e < $dis_e) {
                                unset($schedule[$s][$pos]);
                                $schedule[$s][$pos] = $d;
                                $schedule[$s][$pos]['heure_debut'] = date("H:i",$abs_e);
                                $schedule[$s][$pos]['heure_fin']   = date("H:i",$dis_e);
                                $modified = true;
                                break;
                            }
                            // (6) [ds -de] --- [as  ae] return dispo as is
                            else if($abs_s >= $dis_e){
                                    unset($schedule[$s][$pos]);
                                    $schedule[$s][$pos] =$d;
                                    $modified = false;
                                }
                                // (5)[as  ae] [ds -de] ---  return dispo as is
                                else if($abs_e <= $dis_s){
                                        unset($schedule[$s][$pos]);
                                        $schedule[$s][$pos]= $d;
                                        $modified = false;
                                    }
                                    // (1)[ds] --- [as] --- [ae] --- [de] (duplicate dis with new times)
                                    else if($abs_s > $dis_s && $abs_e <= $dis_e) {
                                            // new times as : // s1 = ds-as &&  s2 = ae-de
                                            unset($schedule[$s][$pos]);
                                            $schedule[$s][$pos]   =$d;
                                            $schedule[$s][$pos+1] =$d;

                                            $schedule[$s][$pos]['heure_debut'] = date("H:i",$dis_s);
                                            $schedule[$s][$pos]['heure_fin']   = date("H:i",$abs_s);
                                            $schedule[$s][$pos + 1]['heure_debut'] = date("H:i",$abs_e);
                                            $schedule[$s][$pos + 1]['heure_fin']   = date("H:i",$dis_e); 
                                            //$pos++;
                                            $modified = true;
                                            break;
                                        }
                                        // (3)[as] -- [ds] --- [ae] -- [de]
                                        else if($abs_s < $dis_s && $abs_e < $dis_e) {
                                                unset($schedule[$s][$pos]);
                                                $schedule[$s][$pos] =$d;
                                                $schedule[$s][$pos]['heure_debut'] = date("H:i",$abs_e);  
                                                $schedule[$s][$pos]['heure_fin']   = date("H:i",$dis_e);
                                                $modified = true;
                                                break;  
                                            }
                                            // (4) [ds]---[as]--- [de]--- [ae]
                                            else if($abs_s > $dis_s && $abs_s < $dis_e && $abs_e > $dis_e) {
                                                    unset($schedule[$s][$pos]);
                                                    $schedule[$s][$pos] =$d;
                                                    $schedule[$s][$pos]['heure_debut'] = date("H:i",$dis_s);  
                                                    $schedule[$s][$pos]['heure_fin']   = date("H:i",$abs_s);
                                                    $modified = true;
                                                    break;
                                                }
                                                else {$modified = false ;}
                    }
                } else {$modified =false;} 
                $pos++; 
            } 
        }
    }
    else {$modified = false;}


    if($modified) {
        $schedule = removeSessionsFromSchedule($schedule,$remove);  
    }

    return $schedule;  
}

時間をマージする関数:

  function mergeSessionFromSchedule($schedule ,$seances) {

    $sessions = removeSessionsFromSchedule($schedule,$seances);

    $mergedSessions = array_merge_recursive($sessions , $seances);

    foreach($mergedSessions as $s => $val) {
        $sortedSessions[$s] = subval_sort_by_time($val,'heure_debut'); 
    }



    return $sortedSessions ;
   }

ヘルパー:

    function subval_sort_by_time($a,$subkey) {
        foreach($a as $k=>$v) {
        $b[$k] = strtotime($v[$subkey]);
        }
    asort($b);
    foreach($b as $key=>$val) {
        $c[] = $a[$key];
    }
    return $c;

}

4

1 に答える 1

1

これが私の解決策です:

<?php

class SessionHandler {
    private $keys   = array();
    private $times  = array();
    private $slots  = array();
    private $merged = array();

    function __construct($available, $assigned) {
        $this->times = array(
            'available' => $available,
            'assigned'  => $assigned
        );
        $this->slots = array(
            'available' => array(),
            'assigned'  => array(),
            'excluded'  => array()
        );
        $this->getKeys($this->times['available']);
        $this->loadSessions($this->keys[0], $this->keys[1]);
    }

    private function getKeys($arr) {
        if (count($arr)) {
            $this->keys = array_keys($arr[0]);
        } else {
            throw new Exception('Invalid array format');
        }
    }

    private function loadSessions($start, $end) {
        foreach ($this->times as $type => $periods) {
            foreach ($periods as $hours) {
                $this->slots[$type][] = $hours[$start].'-'.$hours[$end];
                $this->merged[] = strtotime($hours[$start]);
                $this->merged[] = strtotime($hours[$end]);
            }
        }
        $this->merged = array_unique($this->merged);
        sort($this->merged);

        $hours = $this->times['available'];
        for ($i = 0; $i < count($hours) - 1; $i++) {
            $this->slots['excluded'][] = $hours[$i][$end].'-'.$hours[$i + 1][$start];
        }
    }

    public function mergeSessions() {
        $result = array();
        for ($i = 0; $i < count($this->merged) - 1; $i++) {
            $start_hour = date('H:i', $this->merged[$i]);
            $end_hour   = date('H:i', $this->merged[$i + 1]);
            $slot = $start_hour . '-' . $end_hour;
            if (!in_array($slot, $this->slots['excluded'])) {
                $assigned = in_array($slot, $this->slots['assigned']);
                $result[] = array(
                    $this->keys[0] => $start_hour,
                    $this->keys[1] => $end_hour,
                    'assigned' => $assigned ? "true" : "false"
                );
            }
        }
        return($result);
    }
}


$availability = array(
    '2012-10-07' => array(
        array('start_time' => '08:30', 'end_time' => '13:30'),
        array('start_time' => '16:30', 'end_time' => '23:30')
    )
);

$assignments = array(
    '2012-10-07' => array(
       array('start_time' => '08:30', 'end_time' => '09:30'),
       array('start_time' => '10:30', 'end_time' => '11:30'),
       array('start_time' => '17:00', 'end_time' => '18:30')
    )
);

$sessions = array();

foreach ($availability as $day => $available) {
    $assigned = isset($assignments[$day]) ? $assignments[$day] : array();
    $SH = new SessionHandler($available, $assigned);
    $sessions[$day] = $SH->mergeSessions();
}

?>
<!DOCTYPE html>
<html>
    <body>
        <pre><?php print_r($sessions) ?></pre>
    </body>
</html>
于 2012-10-04T21:06:21.710 に答える