Есть ли простой синтаксис для объявления нескольких ключей с одним значением в perl?

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

вот что-то похожее на то, что я ищу (я на самом деле не знаю, работает ли это или нет):

my $hash = {
             a, b, c => $valA,
             d, e, f => $valB
           };

таких, что....

print $hash->{a}; #prints $valA
print $hash->{b}; #prints $valA
print $hash->{c}; #prints $valA
print $hash->{d}; #prints $valB
print $hash->{e}; #prints $valB
print $hash->{f}; #prints $valB

7 ответов


можно написать так:

my %hash;
$hash{$_} = $valA for qw(a b c);
$hash{$_} = $valB for qw(d e f);

нет, для этого нет простого синтаксиса. (На самом деле, => документирована псевдоним , чей единственный формальный эффект заключается в том, что он позволяет голое слово слева от него даже в строгом режиме).

лучшее, что вы могли бы сделать, не определяя свои собственные подводные лодки может быть что-то вроде

@hash{qw(a b c)} = ($valA) x 3 ;
@hash(qw(d e f)} = ($valB) x 3 ;

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

 @hash{ @keys } = ($value) x @keys;

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

my $value = sub {map {$_ => $_[1]} @{$_[0]}};

my $hash = {
    [qw(a b c)]->$value('valA'),
    [qw(d e f)]->$value('valB'),
};

say join ', ' => map "$_: $$hash{$_}", sort keys %$hash;
# a: valA, b: valA, c: valA, d: valB, e: valB, f: valB

Если вы собираетесь делать это много, вы можете посмотреть на Hash::Util ' s hv_store функция, которая позволяет загружать несколько ключей с точно таким же расположение в памяти.


вы можете использовать назначение хэш-фрагмент:

my $hash = {};

@$hash{a,b,c} = ($valA) x 3;
@$hash{d,e,f} = ($valB) x 3;

назначение может быть сделано и с операторами, например, с map. Здесь карта будет расширена на два списка.

my $hash = {
    ( map { $_ => $valA } ('a' .. 'c') ),
    ( map { $_ => $valB } ('d' .. 'f') ),
};

Да, как указал Хеннинг Макхольм, прямого пути нет, так как => псевдоним ,. Самое близкое к ярлыку, о котором я могу думать, это:

foreach('a','b','c')
{
  $hash->{$_}=$valA;
}

foreach('d','e','f')
{
  $hash->{$_}=$valB;
}