You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl使用splice删除数组连续重复值未达预期原因排查

问题原因
  • 核心问题是你在遍历数组的同时修改了数组的长度,且索引递增逻辑错误导致元素被跳过:
    初始数组为['A','B','B','C'],第一次匹配到索引为1的B时,调用splice删除该位置元素后,原数组变为['A','B','C'],原本第二个B的位置从索引2前移到了索引1。此时你的代码直接执行$j++将索引变为2,下一次循环直接判断索引2的C,就漏掉了移位到索引1的B,最终只删除了一个B。
  • 额外注意:不要用foreach遍历正在被修改的原数组,遍历过程中数组长度变化会导致不可预期的遍历行为。
修正方案

方案1:删除数组中所有值为B的元素

改用while遍历索引,仅在未命中删除逻辑时才递增索引,避免漏判:

use Data::Dumper;
my $tmp_h = {};
@{$tmp_h->{'a'}} = qw/A B B C/;

print Dumper ($tmp_h);

my $j = 0;
# 动态获取数组最大索引,适配长度变化
while ($j <= $#{$tmp_h->{'a'}}) {
    if ($tmp_h->{'a'}[$j] eq 'B') {
        splice(@{$tmp_h->{'a'}}, $j, 1);
    } else {
        $j++;
    }
}
print Dumper $tmp_h;

方案2:通用实现:删除数组中所有相邻重复元素

如果你的需求是删除所有相邻的相同值(不限定是B),更推荐用生成新数组的方式实现,性能更稳定,不会出现索引错位问题:

use Data::Dumper;
my $tmp_h = {};
@{$tmp_h->{'a'}} = qw/A B B C C C D/;

print Dumper ($tmp_h);

my @result;
my $prev_val;
foreach my $cur (@{$tmp_h->{'a'}}) {
    # 仅当前值和上一个保留值不同时才存入结果
    if (!defined $prev_val || $cur ne $prev_val) {
        push @result, $cur;
        $prev_val = $cur;
    }
}
@{$tmp_h->{'a'}} = @result;

print Dumper $tmp_h;

内容的提问来源于stack exchange,提问作者user1550596

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 00:24:03