需手动遍历判断相邻元素大小关系,用$start和$end记录连续严格递增段的起止索引,条件为$arr[$i+1] > $arr[$i],非严格则改用>=。

怎么识别数组里的连续递增段
PHP 本身没有内置函数直接提取「连续递增子序列」,得靠手动遍历判断相邻元素大小关系。关键不是“排序”,而是保持原索引顺序下找 $arr[$i+1] > $arr[$i] 成立的连续区间。
注意:严格递增(不允许相等)还是非严格(允许相等)?多数场景要严格递增,否则 [1,2,2,3] 会被误判为连续段;若需非严格,把 > 换成 >= 即可。
- 从索引
0开始,比较$arr[$i]和$arr[$i+1] - 用两个变量记录当前段起始位置
$start和当前结束位置$end - 一旦
$arr[$i+1] ,就切段,保存array_slice($arr, $start, $end - $start + 1) - 别忘了循环结束后补上最后一段(容易漏)
用 for 循环实现最稳的筛选逻辑
比 foreach 更适合这类带状态的连续判断,因为需要明确访问前后索引。下面这段能正确处理单元素、空数组、全程递增等边界情况:
$arr = [1, 3, 5, 4, 6, 7, 8, 2, 9]; $segments = []; $start = 0;for ($i = 0; $i < count($arr) - 1; $i++) { if ($arr[$i + 1] <= $arr[$i]) { $segments[] = array_slice($arr, $start, $i - $start + 1); $start = $i + 1; } } // 补最后一段 $segments[] = array_slice($arr, $start);
// $segments 现在是 [[1,3,5], [4,6,7,8], [2], [9]]
这里没用 range() 或 array_keys() 等花式写法,就是因为它们无法自然携带「连续性」语义,反而增加理解成本和出错概率。
立即学习“PHP免费学习笔记(深入)”;
用 array_reduce 做函数式写法?慎用
有人想用 array_reduce 一行解决,但实际会踩坑:它按顺序消费元素,却难以在中间「截断并新建子数组」,除非在累加器里嵌套复杂状态(比如同时存当前段和结果集),代码可读性骤降。
- 返回值类型必须一致,
array_reduce的累加器要么全是段、要么全是元素,没法混用 - 无法提前知道何时该切段,导致最后还要后处理合并/拆分
- 调试困难:出错时看不到
$i和$i+1的实时对比
真要用函数式,建议封装成独立函数,内部仍用循环——别为了“看起来函数式”牺牲可维护性。
性能和兼容性要注意什么
纯 PHP 循环筛选的时间复杂度是 O(n),没问题;但若数组超大(比如 10 万+ 元素),要注意内存是否够存所有段(尤其每段都很短时,$segments 数组本身开销不小)。
- PHP 5.6+ 都支持
array_slice,但旧版本对负偏移处理不一致,别传负数 - 如果数组键名重要(比如关联数组),
array_slice默认重置数字键;需要保留原键请加第四个参数true - 浮点数比较要小心:
1.1 + 2.2 !== 3.3,递增判断前建议用round($val, 10)统一精度
连续递增段筛选真正难的不是写出来,而是想清楚「连续」到底指索引连续还是值连续、相等算不算中断、空段要不要过滤——这些细节不定义清楚,代码再短也没用。











