如何在Perl中缩短数组?我读了一些网页,表明我可以指定:
$#ARRAY = 42;
我读到不推荐使用$#。我需要一个适用于数组数组的解决方案。这不起作用:
$#$ARRAY[$i] = 42;
答案 0 :(得分:16)
我不知道指派$#ARRAY
被弃用;来自5.10.0的perldoc perldata
肯定对此一无所知。这是截断数组的最快方法。
如果您想要更具可读性的内容,请使用splice
:
splice @ARRAY, 43;
(注意43
代替42
- $#ARRAY
获取数组的最后一个索引,而splice
获取长度而不是数组。
至于处理数组数组,我假设你的意思是能够通过引用截断嵌套数组?在这种情况下,你想要:
$#{$ARRAY->[7]} = 42;
或
splice @{$ARRAY->[7]}, 43;
答案 1 :(得分:10)
您的选择几乎是无限的(我在此概述了五种方法),但您的策略将取决于您的具体需求和目标。 (所有示例都将@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():
#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
答案 2 :(得分:7)
答案 3 :(得分:5)
你基本上是自己给出了规范的答案。您可以通过设置最后一个索引来缩短数组:
$#Array = 42
表示数组中最后一个索引的$ #Foo表示法绝对不是不。同样,分配给它也不会被弃用。引用perldata文档:
数组的长度是标量值。 您可以找到长度 通过评估$#days 来排列@days,就像在csh中一样。但是,这不是 阵列的长度;它是最后一个元素的下标,是一个 不同的值,因为通常有第0个元素。 分配给 $#days实际上会改变数组的长度。缩短数组 这种方式破坏了干预价值。延长了一个阵列 之前缩短的数据不会恢复那些中的值 元素。 (它曾经在Perl 4中这样做,但我们不得不打破这个 确保在预期时调用析构函数。)
答案 4 :(得分:2)
单独使用
$#{$ array [3]} = 9;
在$ array [3]的autovivified数组中指定长度为9。
如有疑问,请使用Data :: Dumper:
use Data::Dumper;
$#{$array[3]} = 5;
$#array = 10;
print Dumper( \@array, $array ), "\n";
答案 5 :(得分:0)
$#{$ ARRAY [$ i]} = 42;
答案 6 :(得分:0)
你可以做到
splice @array, $length;
#or
splice @{$arrays[$i]}, $length;
答案 7 :(得分:0)
有两种解释问题的方法。
到目前为止,大多数答案都集中在前者身上。在我看来,最好的答案是拼接功能。例如,要从末尾删除10个元素:
splice @array, -10;
但是,由于Perl如何管理数组的内存,确保数组占用较少内存的唯一方法是将其复制到新数组(并回收旧数组的内存)。为此,我倾向于考虑使用 slice 操作。例如,删除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));
}