如何使用pop - Perl从数组数组返回一个数组

时间:2014-06-18 19:12:07

标签: arrays perl

我在Perl中有一个数组数组,我需要后端的数组。我使用pop()并根据其描述它应该返回数组中的最后一个元素(在我的情况下它本身就是一个数组)。但是我注意到pop()返回一个2-D数组(有1行,没有列等于最后一个数组中必须弹出的列数)。我可以以某种方式使pop()只返回一个数组而不是数组数组吗?

3 个答案:

答案 0 :(得分:2)

您知道Perl references吗?

Perl实际上没有一个名为数组数组的数据结构。你拥有的是一个数组,该数组的每个成员都包含另一个数组的内存位置。

当您弹出数组中的某个条目时,您没有获得数组,而是引用到另一个数组。

我正在使用Data::Dumper来查看我的数据结构:

use strict;
use warnings;
use feature qw(say);

use Data::Dumper;

my @array = (
    [ 1, 2, 3 ],
    [ 4, 5, 6 ],
    [ 7, 8, 9 ],
);

say Dumper \@array;

这是我的输出:

$VAR1 = [
        [
            1,
            2,
            3
        ],
        [
            4,
            5,
            6
        ],
        [
            7,
            8,
            9
        ]
        ];

这就是数组的数组......

让我们使用pop来完成最后一行:

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);

use Data::Dumper;

my @array = (
    [ 1, 2, 3 ],
    [ 4, 5, 6 ],
    [ 7, 8, 9 ],
);

my $row_ref = pop @array;  #row_ref _points to_ an array. 

say Dumper  $row_ref;

打印出来:

$VAR1 = [
          7,
          8,
          9
       ];

所以,pop正在发挥作用。它将引用返回给数组。如果我们需要一个实际的数组,我们取消引用引用:

use strict;
use warnings;
use feature qw(say);

use Data::Dumper;

my @array = (
    [ 1, 2, 3 ],
    [ 4, 5, 6 ],
    [ 7, 8, 9 ],
);

my $row_ref = pop @array;      # Returns a reference to an array

my @last_row = @{ $row_ref };  # Dereferencing $row_ref to get @last_row

# Now, we can treat @last_row as our array

for my $index ( 0..$#last_row ) {
    say "\$last_row[$index] = $last_row[$index]";
}

打印出来:

$last_row[0] = 7
$last_row[1] = 8
$last_row[2] = 9

如果你没有得到这样的东西,可能是你的数据结构不是你想象的那样。使用Data::Dumper将其转储。

答案 1 :(得分:0)

my $aoa = [
   [ 'a', 'b' ],
   [ 'c', 'd' ],
   [ 'e', 'f' ],
];

my $last_ele = pop(@$aoa);   # [ 'e', 'f' ]

如果你还有别的东西,你还有别的东西。您可以使用

检查数据结构
use Data::Dumper;

print(Dumper($aoa));   # A scalar
    -or-
print(Dumper(\@aoa));  # A reference
  -but not-
print(Dumper(@aoa));   # XXX This won't show @aoa.

答案 2 :(得分:0)

我认为你正在做这样的事情

my @aoa = (
  [ 'aa', 'ab', 'ac' ],
  [ 'ba', 'bb', 'bc' ],
  [ 'ca', 'cb', 'cc' ],
);

sub return_last_row {
  pop @_;
}

my @last_array = return_last_row(@aoa);

由于@aoa的最后一个元素是数组引用 [ 'ca', 'cb', 'cc' ],因此无法正常工作,因此您获得的等价物

my @last_array = ( [ 'ca', 'cb', 'cc' ] )

即。你现在有一个包含数组引用的单元素数组。

最好的解决方案是接受你有一个参考并使用它,所以调用将是

my $aref = return_last_row(@aoa);

你可以使用

打印第二个元素
print "$aref->[1]\n";

或者,如果你必须有一个真正的数组,那么你可以写

my @arr = @{ return_last_row(@aoa) };

并使用

打印相同的值
print "$arr[1]\n";

注意,但是在第一个选项中,$aref是对曾经是@aoa的最后一个元素的相同数据的引用,所以如果你修改它然后你会改变那些数据。另一方面,它在内存和速度方面比第二个选项更有效,后者将原始数组中的所有数据复制到新数据中。


<强>更新

实际回答你的问题 &#34;我能以某种方式让pop()只返回一个数组而不是一个数组数组吗?&#34; 你可以在子程序中做我上面描述的内容,所以它看起来像这样

sub return_last_row {
  @{ pop @_ };
}

但正如我所描述的,这比仅使用原始数组引用效率低。

此外,确实是否要删除原始@aoa中的最后一个元素?我会更倾向于将它留在原地并且只做

sub return_last_row {
  @{ $_[-1] };
}