Как я могу получить доступ к значениям в двумерном массиве Perl, чтобы иметь их в скалярных переменных? - PullRequest
1 голос
/ 30 сентября 2010

Кажется, я вспоминаю (хотя сейчас не могу найти ссылки), чтобы кто-то мог сделать что-то похожее на

my @a = ("foo","bar");
my ($item1, $item2) = @a;

Вышесказанное не делает то, что я хочу (очевидно), но я, кажется, напоминаю, что есть какой-то способ сделать это, где он загружает элементы, связанные с порядком скаляров в списке в скобках.

Кстати, я подумал, что именно так массив args передается в подпрограммы, как в ...

sub method{
  my ($arg1, $arg2) = @_;
}

Может быть, я просто схожу с ума, но я думал, что это возможно.

[РЕДАКТИРОВАТЬ]

Ах ... поэтому, основываясь на первом ответе, я понимаю, что причина, по которой он не работает, заключается в том, что я использую двумерный массив. Итак, в моем коде это на самом деле выглядит так:

foreach(@twoDimenArray){
    my ($item1, $item2, $item3) = $_; #$_ is an array
}

Должно быть, это искажает синтаксис $, но я пробовал ($_) and @($_) and @$_, и ничего из этого не работает.

Ответы [ 3 ]

6 голосов
/ 30 сентября 2010

Попробуйте использовать @{$_}:

foreach (@twoDimenArray) {
    my ($item1, $item2, $item3) = @{$_};    # $_ is an array
}
4 голосов
/ 30 сентября 2010

То, что у вас есть, работает для меня, то есть это выводит «foo bar»:

use strict;
use warnings;

my @a = ("foo","bar");
my ($item1, $item2) = @a;

print "$item1 $item2\n";

Я использую Perl 5.13.4 на MacOS X 10.6.4, но я не думаю, что это существенный фактор; Я ожидаю, что любой Perl 5.x примет это.


Этот код реализует двумерный массив:

use strict;
use warnings;

my @a;

$a[0][0] = "a00";
$a[0][1] = "a01";
$a[1][0] = "a10";
$a[1][1] = "a11";

my ($item1, $item2) = @a;

print "$item1 $item2\n";

Вывод 'двух ARRAY refs':

ARRAY(0x100803068) ARRAY(0x100826770)

Я не знаю, как можно расширить массив массивов в 4 отдельных значения за одну операцию. Это не совсем то же самое, что «нет способа сделать это».


И, реализуя ваш цикл foreach:

foreach my $array (@a)
{
    my($item1, $item2) = @$array;
    print "$item1 $item2\n";
}

Это печатает:

a00 a01
a10 a11

Этот код является примером из дистрибутива DBD :: Informix - последний раз измененный в 2002 году. Он использует метод fetchall_arrayref(), который возвращает массив ссылок на массивы, как упомянуто в одном из комментариев к вопросу.

#!/usr/bin/perl -w
#
# DBD::Informix Example 5 - fetchall_arrayref
#
# @(#)$Id: x05fetchall_arrayref.pl,v 100.1 2002/02/08 22:50:10 jleffler Exp $
#
# Copyright 1998 Jonathan Leffler
# Copyright 2000 Informix Software Inc
# Copyright 2002 IBM

use DBI;
printf("DEMO1 Sample DBD::Informix Program running.\n");
printf("Variant 4: using fetchall_arrayref()\n");
my($dbh) = DBI->connect("DBI:Informix:stores7") or die;
my($sth) = $dbh->prepare(q%
        SELECT fname, lname FROM customer WHERE lname < 'C'%) or die;
$sth->execute() or die;
my($ref) = $sth->fetchall_arrayref();
foreach $row (@$ref)
{
  printf("%s %s\n", $$row[0], $$row[1]);
}
undef $sth;
$dbh->disconnect();
printf("\nDEMO1 Sample Program over.\n\n");

Если бы я писал сейчас (или обновлял), то было бы использовать use strict;, а также -w (эквивалент use warnings;). Это показывает, что в 2002 году (и с тех пор AFAIK) вы могли написать @$ref достаточно счастливо. В наши дни я, вероятно, написал бы $$row[0] ссылки по-другому - как ${$row}[0].

0 голосов
/ 30 сентября 2010

Для массива refs:

#!/usr/bin/perl

use strict;
use warnings;

my @ary = ( [ qw( foo bar ) ], [ qw( one two ) ], );

my ($ary00, $ary01, $ary10, $ary11) = map { @{ $_ } } @ary;

Для произвольно вложенных массивов:

#!/usr/bin/perl

use strict;
use warnings;

my @ary = (
    [
        qw( foo bar ),
        [
            qw( BAZ QUUX )
        ],
    ],
    [
        qw( ten eleven ),
        [
            'one hundred and twenty',
            'one hundred and twenty-one',
            [
                'one thousand two hundred and twenty',
                'one thousand two hundred and twenty-one',
            ],
        ],
    ],
);

sub flatten {
    my @ary = @_;
    return map { ref($_) eq 'ARRAY' ? flatten( @{ $_ } ) : @{ $_ } } @ary;
}

my ( $a00, $a01, $a020, $a021, $a10, $a11, $a120, $a121, $a1220, $a1221 ) = flatten @a;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...