2009-09-29 7 views
16

Допустим, если у меня есть хэш так:Как заменить хеш-ключ Perl?

$data = { 
    'key1' => { 
       'key2' => 'value1' 
       }, 
    'key3' => { 
       'key4' => { 
          'key5' => 'value2' 
          } 
       }, 
    }; 

Теперь, как я могу заменить ключ «key5» с каким-либо другим именем ключа сказать «key6»? Я знаю, как перебирать хэш & дамп значения, но я не знаю, как заменить ключи или значения на месте. Спасибо за вашу помощь.

ответ

40

Оператор delete возвращает удаляемое значение. Таким образом, это

$data->{key3}{key4}{key6} = delete $data->{key3}{key4}{key5} 

будет делать то, что вы ищете.

+0

О, правильно! Я забыл об этом. Выключить, чтобы изменить мой 'hash_replace()' –

+0

Спасибо за это. Я даже не знал, что это можно сделать так – John

9

Вы не можете заменить его, но вы можете сделать новый ключ легко, а затем delete() старый один:

$data->{key3}{key4}{key6} = $data->{key3}{key4}{key5}; 
delete $data->{key3}{key4}{key5}; 

Конечно, вы могли бы сделать довольно простую подпрограмму, чтобы сделать это. Однако мой первый подход был неправильным, и вам нужно будет сделать более сложный подход, который проходит в структуре данных для модификации, и элемент, который нужно изменить, и учитывая, что вам нужны элементы на несколько уровней, это может быть сложно. Хотя, если вы не возражаете, немного беспорядок:

sub hash_replace (\%$$) { 
    $_[0]->{$_[2]} = delete $_[0]->{$_[1]}; # thanks mobrule! 
} 

Затем вызовите его:

hash_replace %{$data->{key3}{key4}}, "key5", "key6"; 

или прохладный способ (Как лучше сказать, что мы преобразуя «key5» в «key6» ?):

hash_replace %{$data->{key3}{key4}}, key5 => "key6"; 

(Протестировано и работает)

+0

Любая причина для downvote? Что-то здесь не работает? –

+0

Это замечательно, спасибо за помощь. Этот пример действительно хорош для меня, чтобы понять, как подойти к этому. – John

0

Это 'работает', но очень жестко.

#!/bin/perl -w 
use strict; 

my $data = { 
    'key1' => { 
     'key2' => 'value1' 
    }, 
    'key3' => { 
     'key4' => { 
      'key5' => 'value2' 
     } 
    }, 
}; 

print "$data->{key3}->{key4}->{key5}\n"; 

my $save = $data->{key3}->{key4}->{key5}; 
delete $data->{key3}->{key4}->{key5}; 
$data->{key3}->{key4}->{key6} = $save; 

print "$data->{key3}->{key4}->{key6}\n"; 

Вы можете устранить - операторы между хэш-индексами, но не один, после «$» данных «>» - как в решении Криса Луца.

+0

Я всегда предпочитал использовать наименьшее количество '->', с которым мне было бы сойти с рук, но я вижу, как он быстро становится волосатым. –

1

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

use YAML::XS; 
my $yaml = Dump $hash; 
$yaml =~ s/key5/key6/; # may wish for global sub 
$hash = Load $yaml;