Как я могу разыменовать массив массивов в Perl? - PullRequest
1 голос
/ 13 октября 2010

Как разыменовать массив массивов при передаче в функцию?

Я делаю это так:

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

func(\@a);


func{
    @b = @_;

    @c = @{@b};
}

На самом деле я хочу, чтобы массив @c должен содержатьадреса @array1, @array2 и @array3.

Ответы [ 4 ]

8 голосов
/ 13 октября 2010
my @a = {\@array1, \@array2, \@array3};

Выше приведен массив с одним членом -> хеш , содержащий:

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

Поскольку в качестве ключа в хэше Perl приводит ссылку на @array1 в строку. А Perl позволяет скалярной хеш-ссылке быть назначенной массиву, потому что «понятно», что вы хотите массив с первым элементом, который является скаляром, который вы ему присвоили.

Вы создаете массив массивов, например:

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

И тогда в вашей функции вы распакуете их так:

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

Или какой-то другой вариант, например, карта будет самым простым выражением:

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

В вашем примере @c как список адресов - это то же самое, что правильно построенный @a.

5 голосов
/ 13 октября 2010

Вы можете прочитать perldoc perlreftut, perldoc perlref и perldoc 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;

или более компактно:

sub func {
    my $arrayref = shift;

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

func [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];
0 голосов
/ 13 октября 2010

Прочитайте документацию perlreftut .

Редактировать: Другие указывают на хороший момент, который я сначала упустил. При инициализации @a вы, вероятно, имели в виду @a = (...) (создать массив, содержащий ссылки) или $arrayref = [...] (создать ссылку на массив), а не {...} (создать ссылку на хэш). Остальная часть этого поста делает вид, что у вас была @a = (...) версия.

Поскольку вы передаете один аргумент (ссылку на @a) на func, @_ это список, содержащий эту одну ссылку. Вы можете получить эту ссылку и затем разыменовать ее, выполнив:

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

Или в одной строке это будет выглядеть так:

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

(Если бы вы не использовали обратную косую черту в func(\@a), @_ был бы равен @a, массиву трех ссылок.)

0 голосов
/ 13 октября 2010

Должно быть

func {
    $b = shift;
}

если вы передаете ссылку. Надеюсь, что это поможет некоторым.

...