Изменение ключей в цикле for (keys% hash) {} " - PullRequest
3 голосов
/ 12 марта 2010

Я помню кое-что о том, чтобы не менять ключи в

for my $key ( keys %hash ) { ...

например

for my $key ( keys %hash ) {
    $key = "$key_x";
}

Но удаление ключей и изменение значений вполне подойдет. Мои воспоминания в порядке?

Ответы [ 5 ]

12 голосов
/ 12 марта 2010

Я думаю, что вы помните тот факт, что если вы делаете

for my $item (@array) {
    ...
}

добавление или удаление элементов в середине @array (например, с помощью splice) не разрешается, и результат, если вы попытаетесь это сделать, не определен. На самом деле, в старые времена вы могли так и сломать Perl.

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

for my $key (keys %hash) {
    $hash{lc $key} = delete $hash{$key};
}

100% безопасно, не беспокоясь. Я могу пообещать, что это верно в отношении Perl 5.6.1 (апрель 2001 г.), когда в perlfunc было добавлено примечание, что «возвращаемые значения являются копиями», но, похоже, так было всегда, и изменение было в документы.

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

5 голосов
/ 12 марта 2010

См. Функцию keys manpage :

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

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

delete $hash{$key};
$hash{$key} = "foo";
4 голосов
/ 12 марта 2010

Способ сделать это будет

$hash{$newkey} = delete $hash{$oldkey}; 
1 голос
/ 12 марта 2010

вы не можете переименовать любое значение ключа, вместо этого вы можете удалить и создать новое что не меньше, чем переименование ключа! : -)

for my $key ( keys %hash ) {
    delete $hash{$key}; 
    $hash{$key} = "$key_x";
}
0 голосов
/ 12 марта 2010

Но, если вы хотите изменить имя ключа.

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

...