list - Unexpectedly short Perl slices -
the following snippet of perl supposed print first 5 items of array referenced hash value, or fewer if array shorter.
while ( ($key,$value) = each %groups ) { print "$key: \n"; @list = grep defined, @{$value}; @slice = grep defined, @list[0..4]; foreach $item ( @slice ) { print " $item \n"; } print " (", scalar @slice, " of ", scalar @list, ")\n"; } i don't think first grep defined necessary, can't harm, , should guarantee there no undefined array members before slice. second grep defined remove undefined array members in result of slice when @list shorter 5.
%groups has been populated repeated invocations of:
$groups{$key} = () unless defined $groups{$key}; push @{$groups{$key}}, $value; most of time works fine:
key1: value1 value2 value3 value4 value5 (5 of 100) but -- , haven't worked out under circumstances -- see:
key2: value1 (1 of 5) key3: value1 value2 (2 of 5) i expect length of printed list, , x (x of y) min(5,y)
what cause behaviour?
using grep array slice @list autovivifies elements , extends array.
@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 this happens in other contexts perl wants loop on array slice.
@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 so workarounds?
use more complicated expression range or
grepoperand@bar = grep 1, @foo[0..(@foo>=9999?9999:$#foo)]; @bar = grep 1, @foo>=9999 ? @foo[0..9999] : @foo;use temporary array variable
@bar = grep 1, @tmp=@foo[0..9999](suggested @fmc) use
mapset intermediate array@bar = grep 1, map { $list[$_] } 0..9999;work array indices rather directly array
@bar_indices = grep defined($foo[$_]), 0..9999; @bar = @foo[@bar_indices]; @bar = @foo[ grep defined($foo[$_]), 0..9999 ];
Comments
Post a Comment