如何在Perl中收缩数组?
如何在Perl中缩短数组?我阅读了一些网页,表明我可以分配:如何在Perl中收缩数组?,perl,arrays,Perl,Arrays,如何在Perl中缩短数组?我阅读了一些网页,表明我可以分配: $#ARRAY = 42; 我读到$#的用法不受欢迎。我需要一个解决方案,将工作的阵列阵列,太。这不起作用: $#$ARRAY[$i] = 42; $#{$ARRAY[$i]}=42 你可以这样做 splice @array, $length; #or splice @{$arrays[$i]}, $length; 您的选择几乎是无限的(我在这里概述了五种方法),但您的战略将完全取决于您的具体需求和目标。(所有示例将@array
$#ARRAY = 42;
我读到$#的用法不受欢迎。我需要一个解决方案,将工作的阵列阵列,太。这不起作用:
$#$ARRAY[$i] = 42;
$#{$ARRAY[$i]}=42 你可以这样做
splice @array, $length;
#or
splice @{$arrays[$i]}, $length;
您的选择几乎是无限的(我在这里概述了五种方法),但您的战略将完全取决于您的具体需求和目标。(所有示例将@array转换为不超过$N个元素)
[编辑] 正如其他人所指出的,原始问题中建议的方法实际上并没有遭到反对,它提供了最快、最简洁但不一定是最可读的解决方案它还有一个副作用,即用空元素扩展少于$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():
我不知道分配
$#数组被弃用<5.10.0中的code>perldoc perldata
当然没有提到这一点。这是截断数组的最快方法
如果您想要更具可读性的内容,请使用splice
:
splice @ARRAY, 43;
(注意43
而不是42
-$#ARRAY
获取数组的最后一个索引,而splice
获取数组的长度)
至于处理数组的数组,我假设您的意思是能够通过引用截断嵌套数组?在这种情况下,您需要:
$#{$ARRAY->[7]} = 42;
或
- $#数组是数组的最后一个索引李>
- $#$array将是$array指向的数组的最后一个索引李>
- $#$array[$i]表示您正在尝试对标量进行索引,但无法完成$#{$array[3]}在尝试引用最后一个索引之前,正确解析主数组的下标李>
- 单独使用
$#{$array[3]}=9
将长度9指定给$array[3]处的数组
- 如有疑问,请使用Data::Dumper:
use Data::Dumper;
$#{$array[3]} = 5;
$#array = 10;
print Dumper( \@array, $array ), "\n";
基本上你自己给出了标准答案。通过设置最后一个索引缩短数组:
$#Array = 42
表示数组中最后一个索引的$#Foo表示法绝对不受欢迎。同样,分配给它也不会被反对。引用perldata文档:
数组的长度是一个标量值您可以找到
通过计算$#天来数组@days,如在csh中。然而,这不是问题所在
阵列的长度;它是最后一个元素的下标,它是
值不同,因为通常有第0个元素分配给
$#天实际上会改变数组的长度。缩短数组
这种方式会破坏中间的值。延长一个数组的长度
以前缩短的值无法恢复这些值中的值
元素。(在Perl 4中,它曾经这样做,但我们不得不将其打破,以
确保在需要时调用了析构函数。)
该变量已弃用,但$#array
功能未弃用
要对生成数组引用的任意表达式使用$#array
语法,请执行$#{EXPR}
请参阅以下内容:有两种解释问题的方法
- 如何减少数组的长度
- 如何减少阵列占用的内存量
到目前为止,大多数答案都集中在前者。在我看来,最好的答案是拼接功能。例如,要从末端删除10个图元,请执行以下操作:
splice @array, -10;
但是,由于Perl如何管理数组的内存,确保数组占用更少内存的唯一方法是将其复制到新数组(并让旧数组的内存被回收)。为此,我倾向于考虑使用切片操作。例如,要删除10个元素:
@new = @old[ 0 .. $#old - 10 ]
下面是500元素数组(使用2104字节)不同方法的比较:
您可以看到,只有切片操作(复制到新数组)的大小小于原始操作
以下是我用于此分析的代码:
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));
}
$#已弃用,但$#与$#数组不同。我没有在任何地方读到过$#数组被弃用的消息,尽管它让人困惑,我建议不要使用它。这种情况扩展得非常糟糕,特别是当数组中有很多元素,但只删除很少的元素时。这一点很好。我对原始答案进行了扩展,以包含该警告并提供一些其他选项。在第二个示例中,您有一个伪点。起初我将其理解为“42-$#数组”。重新阅读后,我意识到您的意思是:“注意,这里使用43而不是42。$#数组得到您…”。
$#Array = 42
splice @array, -10;
@new = @old[ 0 .. $#old - 10 ]
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));
}