Подтвердить что ты не робот

Perl Как получить массив из хеша массивов?

Я новичок в Perl, так что простите меня, если это похоже на простой вопрос...

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

%HoA = a hash of arrays
$key = some key in the hash

foreach $nextItem (@HoA{$key}) {
  do a bunch of stuff with $nextItem
}

Когда я это делаю, $nextItem всегда равен размеру массива, и цикл работает только один раз. Я пробовал напечатать следующее:

@HoA{$key}
$HoA{$key}
@$HoA{$key}

Первые два дают мне скалярный размер, а третий ничего мне не дает... что мне здесь не хватает?

UPDATE: Мне интересно, действительно ли моя проблема заключается в том, как я добавляю массивы в хэш. Вот что я делаю:

@HoA{$key} = split(/ /, $list);

Поддерживает ли это массив в хэше или размер массива в хеше?

ОБНОВЛЕНИЕ 2: Я пробовал следующий блок кода:

my $key = "TEST";
my %HoA = ();
my @testarray = (1, 2, 3);
@HoA{$key} = @testarray;
print Dumper(%HoA);

Здесь вывод:

$VAR1 = 'TEST';
$VAR2 = 1;

Почему это только приклеивание первого значения массива в?

4b9b3361

Ответ 1

Попробуйте ссылаться на ваш массив следующим образом:

%HoA = a hash of arrays
$key = some key in the hash

foreach $nextItem (@{$HoA{$key}}) {
  do a bunch of stuff with $nextItem
}

Вы берете ссылку на массив в $HoA{$key} и делаете ее массивом.

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

@{$HoA{$key}} = split(/ /, $list);

или вы можете сделать

push(@{$HoA{$key}}, split(/ /, $list);

Например:

my $list = "fred joe brown sam";
my %HoA = ();
my $key = "jacob";
@{$HoA{$key} = split(/ /, $list);
foreach my $item (@{$HoA{$key}})
{
    print "Test item: $nextItem\n";
}

You will get:
Test item: fred
Test item: joe
Test item: brown
Test item: sam

Изменить: Добавьте use strict; в начало вашей программы. В основном вы пытаетесь использовать HoA в качестве массива, если у вас определен хэш. Вы неправильно ссылаетесь на содержимое своего хеша. Для этого вам действительно нужно иметь $ между @ и HoA. Perl является беспричинным и позволит вам избежать убийства, если вы не use strict;. A ссылка от oreilly может прояснить некоторые вещи.

my @testarray - массив my %hash является хешем $hash{$el1} = \@array является элементом hash, который имеет значение ref для массива
@{$hash{$el1}} = @array - хэш-элемент, содержащий массив

Ответ 2

Каждая запись в вашем хэше - это ссылка для массива. Например:

$my_hash{$key}

является ссылкой для массива, а не для массива. $my_hash{$key} просто указывает на область памяти, в которой живет этот массив. Чтобы разыменовать его, вы помещаете символ массива впереди:

@{ my_hash{$key} }

Вещи становятся немного более волосатыми, когда мы начинаем говорить об элементах:

${ my_hash{$key} }[0]

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

$my_hash{$key}->[0];

То же самое, что и выше, но проще понять синтаксис. Иногда проще использовать промежуточные переменные, чтобы вы могли ссылаться на вещи без разыменования:

my %hash_of_array_refs;

foreach my $key (sort keys %hash_of_array_refs) {
    my @array = @{ $hash_of_array_refs{$key} };    #Dereference
    foreach my $element (@array) {                 #Much easier to read and understand
        say "First element is $array[0]";
        say "last element is $array[$#array]";
        say "This element: $element";
    }
}

Без разыменования вы получите следующее:

my %hash_of_array_refs;

foreach my $key (sort keys %hash_of_array_refs) {
    foreach my $element (@{ $hash_of_array_refs{$key} } ) {                 #Much easier to read and understand
        say "First element is " . $hash_of_array_refs->[0];
        say "last element is " . $hash_of_array_refs->[$#{ $hash_of_array_refs{key} } ]";
        say "This element: $element";
    }
}

Ответ 3

@array

Как вы получаете массив, поэтому

@{ $array_ref }

является эквивалентом с ссылкой на массив.

$HoA{$key}

является ссылкой на массив, поэтому

@{ $HoA{$key} }

- это массив.

for my $nextItem (@{ $HoA{$key} }) 

Ответ 4

"Почему он только фиксирует первое значение массива?"

Вам нужно поместить ссылку на ваш массив в хеш, префиксную его обратную косую черту:

$HoA{$key} = \@testarray;

Затем, когда вы извлекаете его из хеша, вы разыскиваете:

@testarray = @{ $HoA{$key} };