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/


Reply via email to