$#ARRAY = 42;
我看到使用$#已经被弃用了。我需要一个能够适用于数组的解决方案,但这个方法并不行:
$#$ARRAY[$i] = 42;
我不知道指定$#ARRAY
已经被弃用了;从5.10.0开始,perldoc perldata
肯定没有关于它的说明。这是截断数组的最快方法。
如果你想要更易读的方法,请使用splice
:
splice @ARRAY, 43;
(请注意使用43
而不是42
- $#ARRAY
会获取数组的最后一个索引,而splice
则需要数组的长度作为参数)。
至于处理嵌套数组,我猜你是指能够通过引用截断嵌套数组吗?在这种情况下,你想要:
$#{$ARRAY->[7]} = 42;
或者splice @{$ARRAY->[7]}, 43;
[编辑]
正如其他人指出的那样,建议使用原始问题中提出的方式实际上并未过时,它提供了最快,最简洁但不一定是最易读的解决方案。它还会导致由少于$N个元素组成的数组扩展为空元素:
$#array = $N-1;
最少的代码:
#best for trimming down large arrays into small arrays
@array = $array[0..($N-1)];
在从大数组中删除少量元素时,最高效的方法:
#This is a little less expensive and clearer
splice(@array, $n, @#array);
除非你真的喜欢delete(),否则在几乎所有情况下都不建议使用:
#this is the worst solution yet because it requires resizing after the delete
while($N-1 < $#array)
{
delete(array[$i]);
}
如果需要将列表的剩余部分按相反顺序排列,则此功能非常有用:
#this is better than deleting because there is no resize
while($N-1 < $#array)
{
pop @array;
#or, "push $array2, pop @array;" for the reverse order remainder
}
有助于长期节省时间:
#don't put more values into the array than you actually want
$#
变量已经过时,但 $#array
特性并未过时。$#array
语法,请执行 $#{ EXPR }
。您基本上已经给出了标准答案。通过设置最后一个索引,可以缩短数组:
$#Array = 42
用$#Foo表示数组中的最后一个索引绝对不会被弃用。同样,对其进行赋值也不会被弃用。引用perldata文档:
数组的长度是标量值。您可以通过评估$#days来查找数组@days的长度,就像在csh中一样。但是,这不是数组的长度;它是最后一个元素的下标,因为通常有第0个元素。 将$#days分配给实际上会改变数组的长度。以这种方式缩短数组会破坏中间值。延长先前缩短的数组不会恢复那些元素中的值。(在Perl 4中曾经这样做,但我们必须打破这个规则,以确保在预期时调用析构函数。)
Used alone
$#{$array[3]} = 9;
assigns a length of 9 to the autovivified array at $array[3].
When in doubt, use Data::Dumper:
use Data::Dumper;
$#{$array[3]} = 5;
$#array = 10;
print Dumper( \@array, $array ), "\n";
你可以这样做
splice @array, $length;
#or
splice @{$arrays[$i]}, $length;
这个问题有两种解释方式。
到目前为止,大多数答案都集中在前者。在我看来,最好的答案是使用 splice 函数。例如,要从末尾删除10个元素:
splice @array, -10;
@new = @old[ 0 .. $#old - 10 ]
这里是一个针对包含500个元素的数组(使用2104字节)的不同方法的比较:
original: length 500 => size 2104
pound: length 490 => size 2208
splice: length 490 => size 2104
delete: length 490 => size 2104
slice: length 490 => size 2064
你可以看到,只有切片操作(复制到新数组)的大小比原始数组小。
这是我用于此分析的代码:
use strict;
use warnings;
use 5.010;
use Devel::Size qw/size/;
my @original = (1 .. 500);
show( 'original', \@original );
my @pound = @original;
$#pound = $#pound - 10;
show( 'pound', \@pound );
my @splice = @original;
splice(@splice,-10);
show( 'splice', \@splice);
my @delete = @original;
delete @delete[ -10 .. -1 ];
show( 'delete', \@delete );
my @slice = @original[0 .. $#original - 10];
show( 'slice', \@slice);
sub show {
my ($name, $ref) = @_;
printf( "%10s: length %4d => size %d\n", $name, scalar @$ref, size($ref));
}
$#{$ARRAY[$i]} = 42;