简体   繁体   English

如何在 Perl 中取消引用数组数组?

[英]How can I dereference an array of arrays in Perl?

How do I dereference an array of arrays when passed to a function?传递给函数时如何取消引用数组?

I am doing it like this:我这样做:

my @a = {\@array1, \@array2, \@array3};

func(\@a);


func{
    @b = @_;

    @c = @{@b};
}

Actually I want the array @c should contain the addresses of @array1 , @array2 , and @array3 .实际上我希望数组@c应该包含@array1@array2@array3

my @a = {\@array1, \@array2, \@array3};

The above is an array with a single member -> a hash containing:上面是一个具有单个成员的数组 -> 一个包含以下内容的哈希

{ ''.\@array1 => \@array2, ''.\@array3 => undef }

Because as a key in the hash, Perl coerces the reference to @array1 into a string.因为作为散列中的键,Perl 会将对@array1的引用@array1转换为字符串。 And Perl allows a scalar hash reference to be assigned to an array, because it is "understood" that you want an array with the first element being the scalar you assigned to it. Perl 允许将标量散列引用分配给数组,因为“理解”您想要一个数组,其中第一个元素是您分配给它的标量。

You create an array of arrays, like so:您创建一个数组数组,如下所示:

my @a = (\@array1, \@array2, \@array3);

And then in your function you would unpack them, like so:然后在您的函数中,您将解压缩它们,如下所示:

sub func {
    my $ref = shift;
    foreach my $arr ( @$ref ) {
        my @list_of_values = @$arr;
    }
}

Or some variation thereof, like say a map would be the easiest expression:或者其中的一些变体,比如地图是最简单的表达方式:

my @list_of_entries = map { @$_ } @$ref;

In your example, @c as a list of addresses is simply the same thing as a properly constructed @a .在您的示例中,作为地址列表的@c与正确构造的@a完全相同。

You may want to read perldoc perlreftut , perldoc perlref , and perldoc perldsc You can say:您可能需要阅读perldoc perlreftutperldoc perlrefperldoc perldsc您可以说:

sub func {
    my $arrayref = shift;

    for my $aref (@$arrayref) {
        print join(", ", @$aref), "\n";
    }
}

my @array1 = (1, 2, 3);
my @array2 = (4, 5, 6);
my @array3 = (7, 8, 9);

my @a = \(@array1, @array2, @array3);

func \@a;

or more compactly:或更紧凑:

sub func {
    my $arrayref = shift;

    for my $aref (@$arrayref) {
        print join(", ", @$aref), "\n";
    }
}

func [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];

Read the perlreftut documentation.阅读perlreftut文档。

Edit: Others point out a good point I missed at first.编辑:其他人指出我一开始错过的一个好点。 In the initialization of @a, you probably meant either @a = (...) (create array containing references) or $arrayref = [...] (create reference to array), not {...} (create reference to hash).在@a 的初始化中,您可能指的是@a = (...) (创建包含引用的数组)或$arrayref = [...] (创建对数组的引用),而不是{...} (创建引用散列)。 The rest of this post pretends you had the @a = (...) version.这篇文章的其余部分假设您拥有@a = (...)版本。

Since you pass one argument (a reference to @a ) to func , @_ is a list containing that one reference.由于您将一个参数(对@a的引用)传递给func ,因此 @_ 是一个包含该引用的列表。 You can get that reference and then dereference it by doing:您可以获取该引用,然后通过执行以下操作取消引用它:

sub func {
  my $arrayref = shift;
  my @c = @{$arrayref};
}

Or in one line, it would look like:或者在一行中,它看起来像:

sub func {
  my @c = @{shift()};
}

(If you hadn't used the backslash in func(\\@a) , @_ would be equal to @a , the array of three references.) (如果您没有在func(\\@a)使用反斜杠, func(\\@a) _ 将等于@a ,即三个引用的数组。)

The following function is designed to take either an array or an array reference and give back a sorted array of unique values.以下函数旨在获取数组或数组引用并返回一个排序的唯一值数组。 Undefined values are removed and HASH and GLOB are left as is.未定义的值被删除,HASH 和 GLOB 保持原样。

#!/usr/bin/perl
use strict; use warnings;

my @one = qw / dog rat / ;
my @two = qw / dog mice / ;
my @tre = ( "And then they said it!", "No!??  ", );
open my $H, '<', $0 or die "unable to open $0 to read";
my $dog; # to show behavior with undefined value
my %hash; $hash{pig}{mouse}=55; # to show that it leaves HASH alone
my $rgx = '(?is)dog'; $rgx = qr/$rgx/; # included for kicks

my @whoo =  (
    'hey!',
    $dog, # undefined
    $rgx,
    1, 2, 99, 999, 55.5, 3.1415926535,
    %hash,
    $H,
    [ 1, 2, 
              [ 99, 55, \@tre, ],
    3, ],
        \@one, \@two,
        [ 'fee', 'fie,' ,
            [ 'dog', 'dog', 'mice', 'gopher', 'piranha', ],
            [ 'dog', 'dog', 'mice', 'gopher', 'piranha', ],
        ],
        [ 1, [ 1, 2222, ['no!', 'no...', 55, ], ], ],
        [ [ [ 'Rat!', [ 'Non,', 'Tu es un rat!' , ], ], ], ], 
        'Hey!!',
        0.0_1_0_1,
        -33,
);


print join ( "\n", 
    recursively_dereference_sort_unique_array( [ 55, 9.000005555, ], @whoo, \@one, \@whoo, [ $H ], ),
    "\n", );
close $H;
exit;

sub recursively_dereference_sort_unique_array
{
    # recursively dereference array of arrays; return unique values sorted. Leave HASH and GLOB (filehandles) as they are.
    # 2020v10v04vSunv12h20m15s
    my $sb_name = (caller(0))[3];
    @_ = grep defined, @_; #https://stackoverflow.com/questions/11122977/how-do-i-remove-all-undefs-from-array
    my @redy = grep { !/^ARRAY\x28\w+\x29$/ } @_; # redy==the subset that is "ready"
    my @noty = grep {  /^ARRAY\x28\w+\x29$/ } @_; # noty==the subset that is "not yet"
    my $countiter = 0;
    while (1)
    {
        $countiter++; 
        die "$sb_name: are you in an infinite loop?" if ($countiter > 99);
        my @next;
        foreach my $refarray ( @noty )
        {
            my @tmparray = @$refarray;
            push    @next, @tmparray;
        }
        @next = grep defined, @next;
        my @okay= grep { !/^ARRAY\x28\w+\x29$/ } @next;
        @noty   = grep {  /^ARRAY\x28\w+\x29$/ } @next;
        push @redy, @okay;
        my %hash = map { $_ => 1 } @redy; # trick to get unique values
        @redy    = sort keys %hash;
        return @redy unless (scalar @noty);
    }
}

Should be应该是

func {
    $b = shift;
}

if you're passing in a reference.如果你传入一个引用。 Hope that helps some.希望能帮到一些人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM