duanbamo0127
2014-04-16 14:51
浏览 21

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条回答 默认 最新

  • duanheye7423 2014-04-16 15:41

    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.

    点赞 评论

相关推荐 更多相似问题