PHP使用start / endtimestamp合并2个数组

I am trying to merge 2 php arrays in a "special" way. I want to "merge" overlapping timestamps. For example take these arrays:

array (size=6)   0 => 
    array (size=2)
      'starttime' => int 1397635320
      'endtime' => int 1397635440   
  1 => 
    array (size=2)
      'starttime' => int 1397635740
      'endtime' => int 1397635920   
  2 => 
    array (size=2)
      'starttime' => int 1397636700
      'endtime' => int 1397637300   
  3 => 
    array (size=2)
      'starttime' => int 1397641260
      'endtime' => int 1397641980   
  4 => 
    array (size=2)
      'starttime' => int 1397642640
      'endtime' => int 1397642760   
  5 => 
    array (size=2)
      'starttime' => int 1397643240
      'endtime' => int 1397647740

And:

array (size=3)
  1 => 
    array (size=2)
      'starttime' => int 1397636580
      'endtime' => int 1397637300
  2 => 
    array (size=2)
      'starttime' => int 1397641080
      'endtime' => int 1397641980
  3 => 
    array (size=2)
      'starttime' => int 1397643120
      'endtime' => int 1397647800

We can display this as: http://upload.mattie-systems.nl/uploads/96059-knipsel.png

I want to merge the bottem one to the top one, however it is possible that the bottom one for example starts BEFORE the top one so in stat case I must have the starttime from the bottom one! (always the "longest" time possible)

I've tried for a few hours but I still cannot get the output i want (one array with the "longest" timespans possible)

Just some code I tried:

  public static function mergeOutageArrays($db_outages, $report_outages)
    {
    $returnarray = array();

    foreach($db_outages as $db_outage)
      {

      $db_starttime = $db_outage['starttime'];
      $db_endtime = $db_outage['endtime'];

      //now match this with report outages

      foreach ($report_outages as $report_outage)
        {
        $report_starttime = $report_outage['starttime'];
        $report_endtime = $report_outage['endtime'];

        if($db_starttime == $report_starttime && $db_endtime == $report_endtime) //easy, everything matches
          $returnarray[] = $report_outage;

        else if($db_starttime == $report_starttime && $db_endtime <= $report_endtime)//seems the db end time falls short, use report
          $returnarray[] = $report_outage;

        else if($db_starttime == $report_starttime && $db_endtime > $report_endtime)//seems the report end time falls short, use db
          $returnarray[] = $db_outage;

        else if($db_starttime <= $report_starttime && $db_endtime == $report_endtime)//seems report starts to late, use db
          $returnarray[] = $db_outage;

        else if($db_starttime > $report_starttime && $db_endtime == $report_endtime)//seems db starts to late, use report
          $returnarray[] = $report_outage;

        elseif($db_starttime <= $report_starttime && $db_endtime > $report_endtime)//we want db
          $returnarray[] = $db_outage;

        elseif($db_starttime > $report_starttime && $db_endtime <= $report_endtime)//we want report
          $returnarray[] = $report_outage;

        else
          //what here
        }
      }
   return $returnarray;
  }

However I'm not getting what I want. Can someone please point me in the right direction or if someone has some example code that would be fantastic!

Again, for every element I need to check if it is (partially) "between" a start/end i already have and if it is bigger "expand" (or relapse) the original entry. If for example it fits right in it means I already have it so I won't need that entry.

edit: Added copy/paste if you want to use my data

    $outage_array = array();
    $outage_array[] = array(1397635320, 1397635440);
    $outage_array[] = array(1397635740, 1397635920);
    $outage_array[] = array(1397636700, 1397637300);
    $outage_array[] = array(1397641260, 1397641980);
    $outage_array[] = array(1397642640, 1397642760);
    $outage_array[] = array(1397643240, 1397647740);

    $report_array = array();
    $report_array[] = array(1397636580, 1397637300);
    $report_array[] = array(1397641080, 1397641980);
    $report_array[] = array(1397643120, 1397647800);

edit: I'll try to describe it better:

Take this image:

http://upload.mattie-systems.nl/uploads/6328-naamloos.png

I have 2 arrays (the red bars) and I want to merge the results to get the blue bar :)

1个回答



如果我正确地阅读了这个问题,你可以删除if-else结构并只使用min / max函数。</ p >

  public static function mergeOutageArrays($ db_outages,$ report_outages)
{
$ returnarray = array();

foreach($ db_outages as $ db_outage){
/ /现在将其与报告中断匹配
foreach($ report_outages as $ report_outage){
$ new_start = min($ report_outage ['starttime'],$ db_outage ['starttime']);
$ new_end = max($ report_outage ['endtime'],$ db_outage ['endtime']);

$ returnarray [] = array($ new_start,$ new_end);
}
}
返回$ returnarray;
} \ n </ code> </ pre>

由于您只引用每个元素一次,因此无需将值复制到变量。</ p>
</ div>

展开原文

原文

If I'm reading this problem right, you can eliminate the if-else construct and just use min/max functions.

public static function mergeOutageArrays($db_outages, $report_outages)
{
    $returnarray = array();

    foreach($db_outages as $db_outage) {
        //now match this with report outages
        foreach ($report_outages as $report_outage) {
            $new_start = min($report_outage['starttime'], $db_outage['starttime']);
            $new_end = max($report_outage['endtime'], $db_outage['endtime']);

            $returnarray[] = array($new_start, $new_end);
         }
    }
    return $returnarray;
}

And since you are only referencing each element once, there is no need to copy the values to a variable.

douan6931
douan6931 因为你的中间情况(你从一个数组开始,另一个数据结束),你必须分别检查开头和结尾,并从适合的那个分配。 你能告诉我哪些情况我的代码不起作用? 当我使用红色输入处理我的代码时,我得到一个映射到蓝色输出的数组。
6 年多之前 回复
douchigu1723
douchigu1723 谢谢你的回复,但不幸的是,这不是我需要的。 我用新图片更新了我的问题,希望能更好地解释我需要的东西。
6 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐