gpt4 book ai didi

perl - 出乎意料的短 Perl 切片

转载 作者:行者123 更新时间:2023-12-04 14:29:50 29 4
gpt4 key购买 nike

下面的 Perl 片段应该打印哈希值引用的数组的前 5 项,如果数组较短,则打印更少。

while ( my ($key,$value) = each %groups ) {
print "$key: \n";
my @list = grep defined, @{$value};
my @slice = grep defined, @list[0..4];
foreach my $item ( @slice ) {
print " $item \n";
}
print " (", scalar @slice, " of ", scalar @list, ")\n";
}

我不认为第一个 grep defined是必要的,但它不会造成任何伤害,并且应该保证切片之前没有未定义的数组成员。第二个 grep defined是在 slice 的结果中删除未定义的数组成员当 @list小于 5。
%groups已被重复调用填充:
  $groups{$key} = () unless defined $groups{$key};
push @{$groups{$key}}, $value;

大多数时候它工作正常:
key1:
value1
value2
value3
value4
value5
(5 of 100)

但有时——我还没有弄清楚在什么情况下——我看到:
key2:
value1
(1 of 5)

key3:
value1
value2
(2 of 5)

我期望打印列表的长度,以及 x来自 (x of y)成为 min(5,y)
什么可能导致这种行为?

最佳答案

使用 grep带有 @list 的数组切片自动激活元素并扩展数组。

@foo = (1,2,3);
@bar = @foo[0..9999];
print scalar @foo; # => 3

@foo = (1,2,3);
@bar = grep 1, @foo[0..9999];
print scalar @foo; # => 10000

这也发生在 Perl 想要遍历数组切片的其他上下文中。
@foo = (1,2,3);
foreach (@foo[0..9999]) { }
print scalar @foo; # => 10000

@foo = (1,2,3);
@bar = map { } @foo[0..9999];
print scalar @foo; # => 10000

那么有哪些解决方法呢?
  • 对范围或 grep 使用更复杂的表达式操作数
    @bar = grep 1, @foo[0..(@foo>=9999?9999:$#foo)];
    @bar = grep 1, @foo>=9999 ? @foo[0..9999] : @foo;
  • 使用临时数组变量
    @bar = grep 1, @tmp=@foo[0..9999]
  • (由@FMc 建议)使用 map设置一个中间数组
    @bar = grep 1, map { $list[$_] } 0..9999;
  • 使用数组索引而不是直接使用数组
    @bar_indices = grep defined($foo[$_]), 0..9999;
    @bar = @foo[@bar_indices];

    @bar = @foo[ grep defined($foo[$_]), 0..9999 ];
  • 关于perl - 出乎意料的短 Perl 切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16443988/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com