Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Perl中收缩数组?_Perl_Arrays - Fatal编程技术网

如何在Perl中收缩数组?

如何在Perl中收缩数组?,perl,arrays,Perl,Arrays,如何在Perl中缩短数组?我阅读了一些网页,表明我可以分配: $#ARRAY = 42; 我读到$#的用法不受欢迎。我需要一个解决方案,将工作的阵列阵列,太。这不起作用: $#$ARRAY[$i] = 42; $#{$ARRAY[$i]}=42 你可以这样做 splice @array, $length; #or splice @{$arrays[$i]}, $length; 您的选择几乎是无限的(我在这里概述了五种方法),但您的战略将完全取决于您的具体需求和目标。(所有示例将@array

如何在Perl中缩短数组?我阅读了一些网页,表明我可以分配:

$#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));
}