yeah, i didn't read the sample output..... so, here ya go. On Sun, Apr 3, 2011 at 6:06 PM, Rob Dixon <rob.di...@gmx.com> wrote: > On 03/04/2011 18:05, Wernher Eksteen wrote: >> Got this to work, but is there a better way to do this? >> >> #!/usr/bin/perl >> >> use strict; >> use warnings; >> >> my ( $val, @matched, @unmatched, %hash1, %hash2 ); >> >> %hash1 = ( >> "emcpowera" => "sdbd sddg sdfj sdhm", >> "emcpoweraa" => "sdae sdch sdek sdgn", >> "emcpowerbc" => "sdb sdbe sddh sdfk", >> "emcpowerc" => "sdbb sdde sdfh sdhk", >> "emcpowerd" => "sdba sddd sdfg sdhj", >> "emcpowerz" => "sdba sddd sdfg sdhj" >> ); >> >> %hash2 = ( >> "emcpowera1" => "/dwpdb006", >> "emcpoweraa1" => "/dwpdb033", >> "emcpowerbc1" => "/s00_11", >> "emcpowerbc2" => "/utl_file_dir", >> "emcpowerc1" => "/odsdb006", >> "emcpowerd1" => "/odsdb005" >> ); >> >> foreach my $i (keys(%hash1)) { >> >> foreach my $b (keys(%hash2)) { >> >> if ($b =~ /$i[0-9]+/) { >> $val = $b;
^^ will error with strict vars. use: my $val = $b; >> push @matched, "$i" . " $hash1{$i} " . "$b" . " >> $hash2{$b} " . "\n"; >> } >> } >> >> if (not $i =~ /$val*/) { how about: if( $i !~ /$val*/ ) but, i would keep my logic the same. >> push @unmatched, "$i" . " $hash1{$i} " . "\n"; >> } >> } >> >> print " @matched"; >> print " @unmatched\n"; >> >> --- RESULT --- >> >> emcpoweraa sdae sdch sdek sdgn emcpoweraa1 /dwpdb033 >> emcpowerd sdba sddd sdfg sdhj emcpowerd1 /odsdb005 >> emcpowerc sdbb sdde sdfh sdhk emcpowerc1 /odsdb006 >> emcpowerbc sdb sdbe sddh sdfk emcpowerbc1 /s00_11 >> emcpowerbc sdb sdbe sddh sdfk emcpowerbc2 /utl_file_dir >> emcpowera sdbd sddg sdfj sdhm emcpowera1 /dwpdb006 >> emcpowerz sdba sddd sdfg sdhj > > I suggest you reduce your tab size from eight characters, which leave > your code spread out and less readable. Four or two is more usual > nowadays. agreed, if you do this and you go 4 or more layers deep, you'll be half way across the page with a tabstep like that. > > Meaningful variable names are also important. Using $i as the key to > %hash1 and $b as the key to %hash2 is a very bad idea: both have > different conventional uses and $b is a special variable used internally > by Perl. > > Long chains of concatenated strings can be improved visually by > interpolation: > > push @matched, "$i $hash1{$i} $b $hash2{$b}\n"; > > or formatting: > > push @matched, sprintf "%s %s %s %s\n", $i, $hash1{$i}, $b, $hash2{$b}; > > As for an improved version, your main purpose seems to be to combine > data that belongs under the same /emcpower.*/ prefix. The program below > does this by modifying %hash1, rather than building two new arrays as > yours does. If this is unacceptable then come back to us. > > The program iterates over the records in %hash2, removes the decimals > from the end of the key, and uses the result to select the record in > %hash1 that should be appended to. > > HTH, > > Rob > > > > use strict; > use warnings; > > my %hash1 = ( > emcpowera => "sdbd sddg sdfj sdhm", > emcpoweraa => "sdae sdch sdek sdgn", > emcpowerbc => "sdb sdbe sddh sdfk", > emcpowerc => "sdbb sdde sdfh sdhk", > emcpowerd => "sdba sddd sdfg sdhj", > emcpowerz => "sdba sddd sdfg sdhj", > ); > > my %hash2 = ( > emcpowera1 => "/dwpdb006", > emcpoweraa1 => "/dwpdb033", > emcpowerbc1 => "/s00_11", > emcpowerbc2 => "/utl_file_dir", > emcpowerc1 => "/odsdb006", > emcpowerd1 => "/odsdb005", > ); > > for my $key2 (keys %hash2) { > (my $key1 = $key2) =~ s/\d+\z//; > if ($hash1{$key1}) { > $hash1{$key1} = "$hash1{$key1} $key2 $hash2{$key2}"; > } > } > > foreach my $key1 (sort keys %hash1) { > print "$key1 $hash1{$key1}\n"; > } > > **OUTPUT** > > emcpowera sdbd sddg sdfj sdhm emcpowera1 /dwpdb006 > emcpoweraa sdae sdch sdek sdgn emcpoweraa1 /dwpdb033 > emcpowerbc sdb sdbe sddh sdfk emcpowerbc1 /s00_11 emcpowerbc2 /utl_file_dir > emcpowerc sdbb sdde sdfh sdhk emcpowerc1 /odsdb006 > emcpowerd sdba sddd sdfg sdhj emcpowerd1 /odsdb005 > emcpowerz sdba sddd sdfg sdhj > > ^^^^ that's shorter and requires less horsepower, but here it is with new hashes (debugged this time :) ). note, the hashes don't print separated, you can define an array (as you've already demonstrated) or loop through them and print each key / val that way (as i've demonstrated). #!/usr/bin/perl use strict; use warnings; my %hash1 = ( "emcpowera" => "sdbd sddg sdfj sdhm", "emcpoweraa" => "sdae sdch sdek sdgn", "emcpowerbc" => "sdb sdbe sddh sdfk", "emcpowerc" => "sdbb sdde sdfh sdhk", "emcpowerd" => "sdba sddd sdfg sdhj", "emcpowerz" => "sdba sddd sdfg sdhj" ); my %hash2 = ( "emcpowera1" => "/dwpdb006", "emcpoweraa1" => "/dwpdb033", "emcpowerbc1" => "/s00_11", "emcpowerbc2" => "/utl_file_dir", "emcpowerc1" => "/odsdb006", "emcpowerd1" => "/odsdb005" ); print "Hash1: ", %hash1, "\n"; print "Hash2: ", %hash2, "\n"; my( %hash3, %nothash ); my $found = 0; while( my( $ikey, $ival ) = each( %hash1 ) ) { print "1: $ikey => $ival\n"; while( my( $jkey, $jval ) = each( %hash2 ) ) { (my $mkey = $jkey ) =~ s/[0-9]//g; print "2: $jkey => $jval\n"; if( $ikey eq $mkey ) { $hash3{ $ikey } = $ival . " " . $jval; $found = 1; } } if( $found == 1 ) { $nothash{ $ikey } = $ival; $found = 0; } } print "Hash3: ", %hash3, "\n"; print "Not found: ", %nothash, "\n"; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/