如何使用 pop 从数组数组返回数组 - Perl [已关闭]

How to return an array from array of arrays using pop - Perl [closed]

提问人:knightcool 提问时间:6/19/2014 更新时间:6/19/2014 访问量:601

问:


想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。

9年前关闭。

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

数组 perl

评论

6赞 mob 6/19/2014
我认为您需要向我们展示您的数组中实际存在的内容(使用或其他工具)。Perl 不支持数组的数组,只支持标量数组(其中标量可以是对数组或其他数据结构的引用)。Data::Dumper
0赞 HerbN 6/19/2014
为了跟进暴民,我想看看你目前在做什么。我怀疑你真的没有数组的数组,甚至没有标量数组(我认为这就是你想要的)。显示代码总是有帮助的。

答:

0赞 ikegami 6/19/2014 #1
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.

评论

0赞 Gabs00 6/19/2014
有趣的是,您提到只将标量传递给 dumper。我尝试只用它做标量引用,因为它看起来很糟糕。但是你这么说是因为数组或引用被扁平化成一个列表,转储器不再显示整个数据结构吗?
0赞 ikegami 6/19/2014
@Gabs00,我有点撒谎。如果您知道使用了 而不是 ,则不会丢失任何信息,但如果您总是传递标量,则不会造成混淆。具体来说,更有可能错过您使用而不是 .用后者的输出来解释错误也更容易。Dumper(@aoa)Dumper(@aoa)Dumper(\@aoa)my @a = [ 'a', 'b', 'c' ]; print(Dumper(@a));[]()print(Dumper(@a));
0赞 Borodin 6/19/2014 #2

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

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


更新

要实际回答您的问题“我可以以某种方式使pop()只返回一个数组而不是数组的数组吗?”您可以在子例程中执行我上面描述的操作,因此它看起来像这样

sub return_last_row {
  @{ pop @_ };
}

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

另外,你真的想从原来的元素中删除最后一个元素吗?我更倾向于把它留在原地,只做@aoa

sub return_last_row {
  @{ $_[-1] };
}
2赞 David W. 6/19/2014 #3

你知道Perl引用吗?

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

当您从数组中弹出一个条目时,您得到的不是一个数组,而是对另一个数组的引用

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

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