我有一个项目数组,它们都有关联的开始和结束日期。我想根据最接近的开始和结束日期对它们进行分组,而不让它们重叠,但是我很难想象这样做的逻辑应该是什么样子的。
假设我从这个开始:
$query = array(
[0] =>
array(
[0] =>
array(
['name'] =>'A'
['start'] =>'1/1/2011'
['end'] =>'1/31/2011'
)
[1] =>
array(
['name'] =>'B'
['start'] =>'1/15/2011'
['end'] =>'1/31/2011'
)
[2] =>
array(
['name'] =>'C'
['start'] =>'2/1/2011'
['end'] =>'2/28/2011'
)
[3] =>
array(
['name'] =>'D'
['start'] =>'2/2/2011'
['end'] =>'2/28/2011'
)
[4] =>
array(
['name'] =>'E'
['start'] =>'1/31/2011'
['end'] =>'3/1/2011'
)
[5] =>
array(
['name'] =>'F'
['start'] =>'3/3/2011'
['end'] =>'3/31/2011'
)
)
)
我想以这个结尾:
$result = array(
[0] =>
array(
[0] =>
array(
['name'] =>'A'
['start'] =>'1/1/2011'
['end'] =>'1/31/2011'
)
[1] =>
array(
['name'] =>'C'
['start'] =>'2/1/2011'
['end'] =>'2/28/2011'
)
[2] =>
array(
['name'] =>'F'
['start'] =>'3/3/2011'
['end'] =>'3/31/2011'
)
)
[1]=>
array(
[0] =>
array(
['name'] =>'B'
['start'] =>'1/15/2011'
['end'] =>'1/31/2011'
)
[1] =>
array(
['name'] =>'D'
['start'] =>'2/2/2011'
['end'] =>'2/28/2011'
)
)
[2]=>
array(
[0] =>
array(
['name'] =>'E'
['start'] =>'1/31/2011'
['end'] =>'3/1/2011'
)
)
)
根据请求编辑,上面列出的输入和输出的var_export:
$query = array ( 0 => array ( 'name' => 'A', 'start' => '1/1/2011', 'end' => '1/31/2011', ), 1 => array ( 'name' => 'B', 'start' => '1/15/2011', 'end' => '1/31/2011', ), 2 => array ( 'name' => 'C', 'start' => '2/1/2011', 'end' => '2/28/2011', ), 3 => array ( 'name' => 'D', 'start' => '2/2/2011', 'end' => '2/28/2011', ), 4 => array ( 'name' => 'E', 'start' => '1/31/2011', 'end' => '3/1/2011', ), 5 => array ( 'name' => 'F', 'start' => '3/3/2011', 'end' => '3/31/2011', ), )
$result = array ( 0 => array ( 0 => array ( 'name' => 'A', 'start' => '1/1/2011', 'end' => '1/31/2011', ), 1 => array ( 'name' => 'C', 'start' => '2/1/2011', 'end' => '2/28/2011', ), 2 => array ( 'name' => 'F', 'start' => '3/3/2011', 'end' => '3/31/2011', ), ), 1 => array ( 0 => array ( 'name' => 'B', 'start' => '1/15/2011', 'end' => '1/31/2011', ), 1 => array ( 'name' => 'D', 'start' => '2/2/2011', 'end' => '2/28/2011', ), ), 2 => array ( 0 => array ( 'name' => 'E', 'start' => '1/31/2011', 'end' => '3/1/2011', ), ), )
到目前为止,我最好的方法是循环遍历$query中的项,并将每个数组中最后一个项的开始日期与结束日期进行比较。即使在我输入这个的时候,我也意识到这将假设我们从一个已经按时间顺序排列的$query数组开始(它是随机的)
我们正在尝试将GANTT时间线与这些数据放在一起,使用尽可能少的行来帮助可视化我们的开放时间表。这把我难住了。谁能指出最有效的组织这些对象的方法,我将不胜感激。
我相信这是答案的开始。
我循环通过$查询和使用unset()对每个对象,因为它被添加到$result内的数组。
希望这里写的内容尽可能高效:
function cmp($a, $b){
return strcmp($a['start'], $b['start']);
}
$query = array(array('name' =>'A','start' =>'1/1/2011','end' =>'1/31/2011'),array('name' =>'B','start' =>'1/15/2011','end' =>'1/31/2011'),array('name' =>'C','start' =>'2/1/2011','end' =>'2/28/2011'),array('name' =>'D','start' =>'2/2/2011','end' =>'2/28/2011'),array('name' =>'E','start' =>'1/31/2011','end' =>'3/1/2011'), array('name' =>'F','start' =>'3/3/2011','end' =>'3/31/2011'));
usort($query, "cmp"); // organize by start date
$result = array();
$c = count($query);
for($i = 1; $i <= $c; $i++) {
if (empty($result)) {
$result[0][0] = $query[0];
unset($query[0]);
$query = array_values($query);
} else {
$lastkey_group = array_pop(array_keys($result));
$lastkey_object = array_pop(array_keys($result[$lastkey_group]));
// get the last object's end date
$last_end_date = strtotime($result[$lastkey_group][$lastkey_object]['end']);
$match_days = 1000;
$match_key = 1000;
foreach($query as $key => $q) {
$this_start_date = strtotime($q['start']);
$diff = round(($this_start_date - $last_end_date)/86400);
// compare to start date in each $q
if($diff < $match_days && $diff >= 0) {
// if the distance is greater than 0 but less than $diff,
// replace match with distance and row key
$match_days = $diff;
$match_key = $key;
}
}
if($match_key == 1000) {
$result[$lastkey_group + 1][0] = $query[0]; // no good matches. write to a new group
unset($query[0]);
$query = array_values($query);
} else {
$result[$lastkey_group][$lastkey_object + 1] = $query[$match_key];
// match. write to this group
unset($query[$match_key]);
$query = array_values($query);
}
}
}
var_dump($result);
下面是它的输出:
array(3) { [0]=> array(3) { [0]=> array(3) { ["name"]=> string(1) "A" ["start"]=> string(8) "1/1/2011" ["end"]=> string(9) "1/31/2011" } [1]=> array(3) { ["name"]=> string(1) "E" ["start"]=> string(9) "1/31/2011" ["end"]=> string(8) "3/1/2011" } [2]=> array(3) { ["name"]=> string(1) "F" ["start"]=> string(8) "3/3/2011" ["end"]=> string(9) "3/31/2011" } } [1]=> array(2) { [0]=> array(3) { ["name"]=> string(1) "B" ["start"]=> string(9) "1/15/2011" ["end"]=> string(9) "1/31/2011" } [1]=> array(3) { ["name"]=> string(1) "C" ["start"]=> string(8) "2/1/2011" ["end"]=> string(9) "2/28/2011" } } [2]=> array(1) { [0]=> array(3) { ["name"]=> string(1) "D" ["start"]=> string(8) "2/2/2011" ["end"]=> string(9) "2/28/2011" } } }