2015-11-16 2 views

ответ

15

Вы должны удалить старые ключи хэша и вставить новые,

use strict; 
use warnings; 

sub rename_keys { 

    my ($hash, $func) = @_; 

    my @k1 = my @k2 = keys %$hash; 
    $func->() for @k2; 
    @$hash{@k2} = delete @$hash{@k1}; 
} 

my %hash = (
'IRQ_VSAFE_LPM_ASC_0' => '140', 
'IRQ_VSAFE_LPM_ASC_1' => '141', 
); 
rename_keys(\%hash, sub { s/ASC_/ASC_1/ }); 
+0

https://eval.in/469460 –

+0

Его рабочий штраф. Спасибо большое :) Я пытаюсь понять, как он работает. Я не получаю эту строку $ func ->() для @ k2. Покой я понял. Не возражаете ли вы разработать? – Grace90

+2

@ Grace90 это ['модификатор foreach'] (http://perldoc.perl.org/perlsyn.html#Statement-Modifiers); вы также можете написать его как 'for (@ k2) {$ func ->()}'. '$ func' - анонимная функция, которая предоставляется как второй аргумент и работает на' $ _', тем самым изменяя/заменяя все элементы массива '@ k2'. –

2

Предыдущий ответ был рассмотрен способ сделать то, что вы хотите. Однако также имеет смысл объяснить, почему то, что вы пытались сделать, не сработало.

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

То, что вы видите в коде Perl просто две части информации: ключевой хэш и соответствующее значение хеш-функции: $myHash{$key} = $value; или даже больше вводит в заблуждение %myHash = ($key => $value);

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

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

2

Простым способом может быть использование pairmap из последних List::Util.

use 5.014; # so we can use the /r flag to s/// 
use List::Util qw(pairmap); 

my %new = pairmap { ($a =~ s/ASC_/ASC_1/r) => $b } %oldhash; 
Смежные вопросы