Как игнорировать последовательность ключей хеша в Perl - PullRequest
0 голосов
/ 23 мая 2018

У меня есть файл, который содержит информацию, подобную приведенной ниже

1:2=14
3:4=15
2:1=16
4:3=17

Я хотел бы создать хэш, который обрабатывает ключ {1:2} так же, как ключ {2:1}

$hash{1:2} = $hash{2:1}

, поэтомукогда я печатаю все элементы в $hash{1:2} или $hash{2:1}, в результате я получаю 14 и 16.Это простой способ сделать это?

Ниже я планирую создать ключ для хэша

for ( my $i = 0; $i <=$#file ; $i++) {
    my $line = $file[$i];
    my @key = split ("=",$line);
    my $hash{$key[0]} = $key[1];
}

1 Ответ

0 голосов
/ 23 мая 2018

Нет встроенного способа сделать это.Если ваши ключи следуют одному и тому же шаблону, вы можете заключить его в функцию, а затем вычислить все ключи, которые соответствуют вашему алгоритму, и получить значения.

my %hash = (
    '1:2' => 14,
    '3:4' => 15,
    '2:1' => 16,
    '4:3' => 17,
);

sub get_elements {
    my ($key) = @_;

    return $hash{$key}, $hash{reverse $key}; # or $key =~ s/(\d+):(\d+)/$2:$1/r
}

print join ' ', get_elements('1:2');

При этом используется строка reverseи, очевидно, работает только в том случае, если части ключа состоят только из одной цифры.Если у вас может быть число больше 9, вам придется разбить строку и собрать ее заново или использовать подстановку для их переключения.В моем примере используется модификатор /r, для которого требуется Perl 5.14 или выше .


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

use strict;
use warnings;
use feature 'say';
use Data::Dumper;

my %hash;
while (my $line = <DATA>) {
    chomp $line;
    my ($key, $value) = split /=/, $line;
    my ($left, $right) = split /:/, $key;

    # $hash{$key} //= ( $hash{"$right:$left"} // [] ); # needs 5.10
    $hash{$key} = ( $hash{"$right:$left"} || [] )
        unless exists $hash{$key};

    push @{ $hash{$key} }, $value;
}

say "@{ $hash{'1:2'} }";
say "@{ $hash{'2:1'} }";

print Dumper \%hash;

__DATA__
1:2=14
3:4=15
2:1=16
4:3=17

Вывод этого кода:

14 16
14 16

Структура Data :: Dumper выглядит следующим образом, что объясняет, что оба ключа 2:1 и 1:2 указывают на одну и ту же ссылку на массив.Это означает, что если вы добавите push другое значение в одно из них, оно также окажется в другом, потому что на самом деле это одно и то же.

$VAR1 = {
          '4:3' => [
                     '15',
                     '17'
                   ],
          '3:4' => $VAR1->{'4:3'},
          '2:1' => [
                     '14',
                     '16'
                   ],
          '1:2' => $VAR1->{'2:1'}
        };

Единственный недостаток этого заключается в том, что выне может получить порядок элементов обратно.Эта структура данных теряет знание, что 1:2 имел значение 14, а 2:1 изначально 16.Если вы хотите, чтобы 2:1 вывел 16 14, это не сработает.

...