Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

simplify the code

by Anonymous Monk
on Oct 09, 2005 at 14:39 UTC ( [id://498567]=perlquestion: print w/replies, xml ) Need Help??

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

Hi,
Is there any shortest method to write the code. I would like to simplify this code.
#!/usr/bin/perl $sur = [ { 'one' => 'USA', 'two' => 'GOD', 'three' => '690 +557','four'=>'hello how are u',}, { 'one' => 'USA', 'two' => 'GOD', 'three' => '690 +557','four'=>'I am fine',}, { 'one' => 'UK', 'two' => 'GOD', 'three' => '6905 +58','four'=>'I am Okay',}, ]; @array = @$sur; %hash1=(); foreach $key(@array) { %hash2 = %$key; $one = $hash2{one}; $two = $hash2{two}; $three = $hash2{three}; $four = $hash2{four}; $firstrow = $one."<-->".$two."<-->".$four; if($hash1{$three} ne "") { $hash1{$three} = $hash1{$three}."####".$four; } else { $hash1{$three} = $firstrow; } } ############## Output ######################## #while(($k,$v) = each(%hash1)) #{ #print "$k----->$v\n"; #} #Result Hash contain #'690557'=>'USA<=>GOD<=>hello how are u####I am fine' #'690558'=>'UK<=>GOD<=>I am Okay' ############## End ###########################

Replies are listed 'Best First'.
Re: simplify the code
by Zaxo (Archbishop) on Oct 09, 2005 at 15:01 UTC

    You don't need all those temporary variables in your loop,

    for (@$sur) { my $firstrow = join '<-->', @{$_}{qw/one two four/}; $hash1{$_->{'three'}} .= $hash1{$_->{'three'}} ? '####'.$_->{'four'} : $firstrow; }

    Update: The whole loop in a single statement:

    $hash1{$_->{'three'}} .= $hash1{$_->{'three'}} ? '####' . $_->{'four'} : join( '<-->', @{$_}{qw/one two four/}) for @$sur;
    No temporaries at all.

    After Compline,
    Zaxo

      I wrote basically the same solution, but like having the loop variable (esp. since there's a use of $_ in the map.)

      We both changed the conditional in different ways, from ne '' in the original to evaluates true in yours, and to existence in mine.

      for my $hashref (@$sur) { if (exists $hash1{$hashref->{three}}) { $hash1{$hashref->{three}} .= "####$hashref->{four}"; } else { $hash1{$hashref->{three}} = join '<-->', map $hashref->{$_}, (qw(o +ne two four)); } }

      The second one looks quite intimidating, IMHO. The first one could be clearer if you chose your temporary variables just a tad better. The code I ended up writing looks is almost identical to your first loop, except for the choice of temporaries; and I think it looks a lot clearer.

      Makeshifts last the longest.

Re: simplify the code
by polettix (Vicar) on Oct 09, 2005 at 15:02 UTC
    I suggest using strict</code> and <c>warnings, just to be on the safe side. Variable $sur doesn't seem to be necessary, you can write directly:
    my @array = ( { one => 'USA', ... }, {...}, ... );
    I also wonder why you need hashes inside the array, and why you don't use (anonymous) arrays:
    my @array = ( [ 'USA', 'GOD', '690557', 'hello how are u' ], [ ... ], + ... );
    which lets you say:
    foreach my $aref (@array) { # If you really need them... my ($one, $two, $three, $four) = @$aref; # Etc. etc. }

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
Re: simplify the code
by Aristotle (Chancellor) on Oct 09, 2005 at 16:32 UTC
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @sur = ( { one => 'USA', two => 'GOD', three => 690557, four => 'hello how +are u', }, { one => 'USA', two => 'GOD', three => 690557, four => 'I am fine' +, }, { one => 'UK', two => 'GOD', three => 690558, four => 'I am Okay' +, }, ); my %h; foreach my $row ( @sur ){ my $three = $row->{ three }; $h{ $three } .= exists $h{ $three } ? "####" . $row->{ four } : join "<-->", @{ $row }{ qw/one two four/ }; } print Dumper \%h;

    As mentioned by others your data structure seems a bit strange, but maybe it’s just example code.

    Makeshifts last the longest.

Re: simplify the code
by davidrw (Prior) on Oct 09, 2005 at 15:09 UTC
    first comment is that you should use strict; and use warnings; ..next, i think this shortens it up:
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $sur = [ { 'one' => 'USA', 'two' => 'GOD', 'three' => '690 +557','four'=>'hello how are u',}, { 'one' => 'USA', 'two' => 'GOD', 'three' => '690 +557','four'=>'I am fine',}, { 'one' => 'UK', 'two' => 'GOD', 'three' => '6905 +58','four'=>'I am Okay',}, ]; my %h; foreach ( @$sur ){ if( exists $h{ $_->{three} } ){ $h{ $_->{three} } .= "####" . $_->{four}; }else{ $h{ $_->{three} } = join "<-->", @{$_}{ qw/one two four/ }; } } print Dumper \%h;
    I have to wonder though why @$sur is a hash with those keys instead of just an array ... can you explain where that data structure is coming from/what it's for?
Re: simplify the code
by ides (Deacon) on Oct 09, 2005 at 14:58 UTC

    Yeah you can simplify it a bit:

    #!/usr/bin/perl use strict; my $sur = [ { 'one' => 'USA', 'two' => 'GOD', 'three' => '690557', 'four' => 'h +ello how are u', }, { 'one' => 'USA', 'two' => 'GOD', 'three' => '690557', 'four' => 'I + am fine', }, { 'one' => 'UK', 'two' => 'GOD', 'three' => '69058', 'four' => 'I +am Okay', }, ]; my %hash1; foreach my $key ( @{$sur} ) { my $firstrow = $$key{one} . '<-->' . $$key{two} . '<-->' . $$key{four}; if( $hash1{ $$key{three} } ne '' ) { $hash1{ $$key{three} } = $hash1{ $$key{three} } . '####' . $key{four}; } else { $hash1{ $$key{three} } = $firstrow; } }

    Frank Wiles <frank@wiles.org>
    http://www.wiles.org

Re: simplify the code
by ysth (Canon) on Oct 09, 2005 at 20:34 UTC
    It seems to me that your initial datastructure isn't what you want; is it possible you could change it when you are collecting the data initially to something like:
    { '690557' => [ { 'one' => 'USA', 'two' => 'GOD', 'four'=>'hello how are u' } +, { 'one' => 'USA', 'two' => 'GOD', 'four'=>'I am fine' } ], '690558' => [ { 'one' => 'UK', 'two' => 'GOD', 'four'=>'I am Okay' } ] }
    or maybe:
    { '690557' => { 'one' => 'USA', 'two' => 'GOD', 'four'=> [ 'hello how are u', 'I am fine' ] }, '690558' => { 'one' => 'UK', 'two' => 'GOD', 'four'=> [ 'I am Okay' ] } }
    Don't copy a from a reference to an array or hash variable just to get things out of it; just do for ... ( @$arrayref ) and $hashref->{$key}; see references quick reference for guidance.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://498567]
Approved by theroninwins
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2024-04-25 02:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found