php中压缩数组连续相同元素常用行程长度编码(rle),遍历合并相邻重复项为[值,次数],需初始化当前值与计数器,遍历时累加或存入结果,末组勿遗漏。

PHP 中压缩数组里连续相同元素,常用方法是“行程长度编码”(Run-Length Encoding,RLE),核心思路是遍历数组,把相邻重复值合并为 [值, 重复次数] 或直接简化为单个值(去重但保持顺序)。关键在“连续”,不处理非相邻的重复项。
基础实现:转成 [值, 次数] 格式
适用于需要保留频次信息的场景,比如日志统计、数据序列压缩。
- 初始化空结果数组,记录当前元素和计数器
- 从索引 0 开始遍历,遇到相同值就累加计数;不同则把上一组存入结果,并重置当前值和计数
- 别忘了把最后一组追加进去
$arr = ['a', 'a', 'b', 'b', 'b', 'c'];
$result = [];
if (!empty($arr)) {
$current = $arr[0];
$count = 1;
for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] === $current) {
$count++;
} else {
$result[] = [$current, $count];
$current = $arr[$i];
$count = 1;
}
}
$result[] = [$current, $count]; // 最后一组
}
// 输出: [['a',2], ['b',3], ['c',1]]
简洁去重:只留一个代表(类似 array_unique 但保序且仅限连续)
这是最常用的“压缩”含义——把 [1,1,1,2,2,3,3,3,3] 变成 [1,2,3],注意它和 array_unique() 不同:array_unique() 去所有重复,而这个只合并相邻的。
- 用
array_reduce()累积时判断末尾是否相同 - 或更直观:用
foreach遍历,只在值变化时追加到新数组
$arr = [1,1,1,2,2,3,3,3,3];
$compressed = [];
$prev = null;
foreach ($arr as $item) {
if ($item !== $prev) {
$compressed[] = $item;
$prev = $item;
}
}
// 输出: [1,2,3]
一行函数封装(可复用)
把逻辑包成函数,便于多次调用。支持两种模式:频次模式或去重模式。
立即学习“PHP免费学习笔记(深入)”;
function compressArray($arr, $mode = 'unique') {
if (empty($arr)) return [];
$result = [];
$current = $arr[0];
$count = 1;
for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] === $current) {
$count++;
} else {
if ($mode === 'rle') {
$result[] = [$current, $count];
} else {
$result[] = $current;
}
$current = $arr[$i];
$count = 1;
}
}
if ($mode === 'rle') {
$result[] = [$current, $count];
} else {
$result[] = $current;
}
return $result;
}
// 使用:
compressArray(['x','x','y','z','z','z'], 'rle'); // [['x',2],['y',1],['z',3]]
compressArray(['x','x','y','z','z','z']); // ['x','y','z']
注意事项与边界情况
- 空数组或单元素数组需单独判断,避免下标越界
- 注意类型严格比较(
===),防止'1'和1被误判为相同 - 如果数组含对象或复杂结构,需自定义比较逻辑(PHP 默认用
==或===比较引用/值,可能不符合预期) - 大数据量时,避免在循环中频繁调用
count(),可提前赋值











