Perl: объединение значений двух массивов хэшей и превращение значений второго массива в ключи выходного хэша

#perl #hash-of-hashes #arrayofarrays

#perl #хэш-хэшей #arrayofarrays

Вопрос:

Извините, если то, что я называю массивом хэшей, — это что-то другое. С этого момента я буду просто называть эти вещи «структурами». В любом случае, допустим, у меня есть две структуры:

 my @arrayhash;
push(@arrayhash, {'1234567891234' => 'A1'});
push(@arrayhash, {'1234567890123' => 'A2'});
 

и

 my @arrayhash2;
push(@arrayhash2, {'1234567891234' => '567'});
push(@arrayhash2, {'1234567890123' => '689'});
 

Как я могу получить выходные данные:

 @output= {
  '567' => 'A1',
  '689' => 'A2',
}
 

Ни в одной структуре не будет отсутствующих элементов, и также не будет значений ‘undef’.

Комментарии:

1. Могут ли ваши хэши содержать более одной пары ключ-значение? добавляются ли хэши в массив в том же порядке, Т.Е. Если я нахожу хэш с ключом xyz в индексе 5 массива, уверен ли я, что тот же ключ xyz будет в индексе 5 массива 2? или они упорядочены по-разному?

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

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

4. Каждый ключ может появиться только один раз

Ответ №1:

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

 #!/usr/bin/perl

use strict;
use warnings;

my @arrayhash;
push @arrayhash, {'1234567891234' => 'A1'};
push @arrayhash, {'1234567890123' => 'A2'};

my @arrayhash2;
push @arrayhash2, {'1234567891234' => '567'};
push @arrayhash2, {'1234567890123' => '689'};

my %hash; # temporary hash holding all key => value pairs in arrayhash
foreach my $h (@arrayhash) {
    while( my($k,$v) = each %$h) {
        $hash{$k} = $v;
    }
}

my %output;
foreach my $h (@arrayhash2) {
    while( my($k,$v) = each %$h) {
        $output{$v} = $hash{$k};
    }
}

my @output=(%output);
 

Ответ №2:

 # Build $merged{$long_key} = [ $key, $val ];
my %merged;
for (@arrayhash2) {
   my ($k, $v) = %$_;
   $merged{$k}[0] = $v;
}   

for (@arrayhash) {
   my ($k, $v) = %$_;
   $merged{$k}[1] = $v;
}

my %final = map @$_, values(%merged);
 

или

 # Build $lookup{$long_key} = $key;
my %lookup;
for (@arrayhash2) {
   my ($k, $v) = %$_;
   $lookup{$k} = $v;
}   

my %final;
for (@arrayhash) {
   my ($k, $v) = %$_;
   $final{ $lookup{$k} } = $v;
}