satzbu has asked for the wisdom of the Perl Monks concerning the following question:

please help me to debug this error i have an error report like missing $ on loop at hashreplace.pl this is my code

#!/usr/bin/perl use warnings; use strict; use Data::Dumper; my %xhash = ('a' => { 'b' => { 'e' => 'E', 'c' => 'C', 'content' => 'B ' }, 'content' => 'A ', 'd' => 'D' }); my $key = keys(%xhash); print $key; my %c_hash=('a' => { 'addval' => { 'b' => { 'addval' => { 'e' => { 'addv +al' => {}, 'repv +al' => '5' }, 'c' => { 'addv +al' => {}, 'repv +al' => '3' } }, 'repval' => '2' }, 'd' => { 'addval' => {}, 'repval' => '4' } }, 'repval' => '1' }); print $c_hash{'a'}{'repval'}; foreach keys($xhash){ keys(%xhash)=$c_hash{'$key'}{'repval'}; print Dumper $xhash;}

i want to replace xhash keys against c_hash values i mean this output only i want

%xhash = ('1' => { '2' => { '5' => 'E', '3' => 'C', 'content' => 'B ' }, 'content' => 'A ', '4' => 'D' });

Replies are listed 'Best First'.
Re: for loop error
by roboticus (Chancellor) on Apr 13, 2010 at 11:32 UTC

    satzbu:

    You might want to try reading perlsyn so you can review the syntax of the for and foreach statement. Because you omitted the (necessary) parenthesis, perl doesn't want to compile your program. Of course, when you fix that one, it'll then whine about your usage of $xhash in the same line. You want that line to read:

    foreach (keys(%xhash)) {

    ...roboticus

Re: for loop error
by almut (Canon) on Apr 13, 2010 at 12:54 UTC

    If I'm understanding you correctly (i.e. that key names should be changed to the value indicated by 'replval' => ... in the respective %c_hash entry, if such an entry exists), you want something like this:

    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my %xhash = ('a' => { 'b' => { 'e' => 'E', 'c' => 'C', 'content' => 'B ' }, 'content' => 'A ', 'd' => 'D' }); my %c_hash=('a' => { 'addval' => { 'b' => { 'addval' => { 'e' => { 'addv +al' => {}, 'repv +al' => '5' }, 'c' => { 'addv +al' => {}, 'repv +al' => '3' } }, 'repval' => '2' }, 'd' => { 'addval' => {}, 'repval' => '4' } }, 'repval' => '1' }); sub traverse { my ($hash, $callback, $mode) = @_; return unless ref($hash) eq "HASH"; for my $key (keys %$hash) { my $val = $hash->{$key}; if (ref($val) eq "HASH") { traverse($val, $callback, $mode); if ($mode eq "collect") { if (exists $val->{repval}) { $callback->($key, $val->{repval}); } } } if ($mode eq "replace") { $callback->($key, $val, $hash); } } } my %repl; # lookup table: a => 1, etc. traverse(\%c_hash, sub { my ($key, $val) = @_; $repl{$key} = $val; }, "collect" ); # print Dumper \%repl; # debug traverse(\%xhash, sub { my ($key, $val, $href) = @_; if (exists $repl{$key}) { my $newkey = $repl{$key}; $href->{$newkey} = $val; delete $href->{$key}; } }, "replace" ); print Dumper \%xhash; __END__ $VAR1 = { '1' => { '4' => 'D', 'content' => 'A ', '2' => { '3' => 'C', 'content' => 'B ', '5' => 'E' } } };

    Note that as you can't rename hash keys, you have to create new key-value pairs (new key, old value), while deleting the old entries.

      mam when i change my input hash as the grouping means it cant replace the keys what changes i made on that code please tell mam its very urgent this is my input

      my %xhash = ('a' => [{ 'b' => [{ 'e' => 'E', 'c' => 'C', 'content' => 'B ' }], 'content' => 'A ', 'd' => 'D' }]);
Re: for loop error
by apl (Monsignor) on Apr 13, 2010 at 11:23 UTC
    You use foreach keys($xhash)

    Either use $_ as the key to your hash in the loop or explicitly specify foreach my $k keys($xhash)

      I think the real problem here is the missing parens

      foreach ( keys(%xhash) ) {

      because of which Perl interprets keys as a variable name, and complains about the missing sigil...  —> use diagnostics;

      Also, it should be %xhash, not $xhash.