我有一个数组,它有开始日期,结束日期和价格,例如.

/* date formate 'yyyy-mm-dd' */

$existingRanges = [
  ['start_date' => '2023-11-22', 'end_date' => '2023-11-30', 'price' => 200],
  ['start_date' => '2023-12-10', 'end_date' => '2023-12-14', 'price' => 100],
  ['start_date' => '2023-12-15', 'end_date' => '2023-12-20', 'price' => 100],
  ['start_date' => '2023-12-21', 'end_date' => '2023-12-27', 'price' => 100],
  ['start_date' => '2024-01-05', 'end_date' => '2024-01-05', 'price' => 600],
  ['start_date' => '2024-01-06', 'end_date' => '2024-01-07', 'price' => 700],
  ['start_date' => '2024-01-08', 'end_date' => '2024-01-20', 'price' => 700],
  ['start_date' => '2024-01-21', 'end_date' => '2024-01-31', 'price' => 100],
];

我想在这里合并所有的日期是相邻的,但有相同的价格,即100101102103这两个日期范围是相邻的,他们的价格是一样的,所以它应该是100103和价格700.

我的结果数组示例.

$results = [
  ['start_date' => '2023-11-22', 'end_date' => '2023-11-30', 'price' => 200],
  ['start_date' => '2023-12-10', 'end_date' => '2023-12-27', 'price' => 100],
  ['start_date' => '2024-01-05', 'end_date' => '2024-01-05', 'price' => 600],
  ['start_date' => '2024-01-06', 'end_date' => '2024-01-20', 'price' => 700],
  ['start_date' => '2024-01-21', 'end_date' => '2024-01-31', 'price' => 100],
];

我try 的代码/逻辑

function mergeDateRanges($p_arrDateranges) {
  // sort by start date
  /* usort($p_arrDateranges, function($a1, $a2) {
    return $a1['start_date'] === $a2['start_date'] ? 0 : ($a1['start_date'] < $a2['start_date'] ? -1 : 1);
   }); */

   $finalArray = [];
   $arrMerged = array();
   $arrLastDR = null;
   foreach ($p_arrDateranges as $arrDR) {

     if ($arrLastDR === null) {
       $arrLastDR = $arrDR;
       continue;
     }

     if(!$arrMerged) {
      array_push($arrMerged, $arrLastDR);
     }

     $endDate = DateTime::createFromFormat('Y-m-d', $arrLastDR['end_date']);
     $sLastDateE_1 = $endDate->modify('+1 day')->format('Y-m-d');

     if (strtotime($arrDR['start_date']) < strtotime($sLastDateE_1) && $arrDR['price'] == $arrLastDR['price']) {
       array_push($finalArray, [
         'start_date' => $arrDR['start_date'], 
         'end_date' => $arrLastDR['end_date'], 
         'price' => 0
       ]);
     } else {
       array_push($finalArray, $arrDR);
     }

     $arrLastDR = $arrDR;
     array_push($arrMerged, $arrLastDR);
     //print_r($arrLastDR);
 }

 return $finalArray;
}

mergeDateRanges($existingRanges);

这是返回不同的结果,所以请帮助我解决这个问题.

推荐答案

如果上一个结束日期的时间比较等于当前开始日期,以及价格判断,则只将结束日期$arrLastDR更新为当前的结束日期(我们可以称之为合并).

如果它们不匹配,则此合并段仅在此索引之前有效.所以,把它加到$finalArray上,用当前的开始一个新的$arrLastDR.


因此,请更改以下内容

if(!$arrMerged) {
      array_push($arrMerged, $arrLastDR);
     }

     $endDate = DateTime::createFromFormat('Y-m-d', $arrLastDR['end_date']);
     $sLastDateE_1 = $endDate->modify('+1 day')->format('Y-m-d');

     if (strtotime($arrDR['start_date']) < strtotime($sLastDateE_1) && $arrDR['price'] == $arrLastDR['price']) {
       array_push($finalArray, [
         'start_date' => $arrDR['start_date'], 
         'end_date' => $arrLastDR['end_date'], 
         'price' => 0
       ]);
     } else {
       array_push($finalArray, $arrDR);
     }

     $arrLastDR = $arrDR;
     array_push($arrMerged, $arrLastDR);

to

 $endDate = DateTime::createFromFormat('Y-m-d', $arrLastDR['end_date']);
     $sLastDateE_1 = $endDate->modify('+1 day')->format('Y-m-d');

     if (strtotime($arrDR['start_date']) == strtotime($sLastDateE_1) && $arrDR['price'] == $arrLastDR['price']) {
        $arrLastDR['end_date'] = $arrDR['end_date'];
     }else{
        array_push($finalArray, $arrLastDR);
        $arrLastDR = $arrDR;
     }
     
    }
    
    if($arrLastDR !== null){
        array_push($finalArray, $arrLastDR);
    }

Live Demo

Note:不需要任何显式排序,因为您已经确认输入是以排序方式进行的.

Php相关问答推荐

try 修改这个PHP代码如果语句在WordPress""

PHP邮件表单无法识别重音/特殊字符

Nginx重写扩展名为.php的动态URL

创建一个新的可变产品及其属性以用于WooCommerce中的变体

Symfony 6.2 IsGraned具有多个角色

筛选器具有多个查询之一

在Laravel中从动态嵌套数组中获取值

如何将LARAVEL模块路径和项目路径合并,因为当我使用模块路径时,它们会覆盖项目路径

Laravel 10中的Validator类

可以';exec、system和shell_exec PHP函数中的命令字符串上的字符数不得超过8175

按类别层次 struct 过滤 Laravel 集合

在 php 中生成 MAC ISO/IEC 9797-1

安装 Herd 并返回 Valet 后为 502

在 vue 自定义渲染器中访问变量

Laravel 发送邮箱问题 Swift_TransportException

URL中包含"&"与DirectoryIterator不兼容

使用其ID查询和捕获与订单相关的其他详细信息的shopware 6方法

yii2 sql迁移覆盖新更改的记录

如何在不解压缩/重新压缩的情况下连接(连接)两个缩小的值

PHP Remedy API 调用以创建附件无效的条目(使用 Postman Works!)