Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Sorting hash

by vsailas (Beadle)
on Feb 21, 2008 at 11:18 UTC ( [id://669239]=perlquestion: print w/replies, xml ) Need Help??

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

Hello all,

I seek your help in resolving an issue at hand.
I have this code:
$a have a string, $b has a reference to an array(\@array1), $c is count of array at $b.
while(<FH>){ my($a,$b,$c)= split(',' , $_); push( @Data, { 'meth' => $a, 'list' => $b, 'count' => $c } ); }

I want to sort '@Data'(ascending), using '$a', a string and
all '$b','$c' must be carried along with $'a'.

Also  $dd{'1'}{'2'}{'3'}="hi"; how can I get the value used at second place '2' here.
I use   %{$dd{'1'}};
but it returns something like '2HASH(0x225e44)'

Thanking all in advance,
Sailas

Replies are listed 'Best First'.
Re: Sorting hash
by stiller (Friar) on Feb 21, 2008 at 11:50 UTC
    use strict; use warnings; use Data::Dumper; # nice my @Data; # bad name, what does it store? while(<DATA>){ my($meth,$list,$count)= split ','; push @Data, { 'meth'=>$meth, 'list'=>$list, 'count'=>$count }; } print "Unsorted:\n", Dumper( @Data ), "\n"; @Data = sort { $a->{'meth'} cmp $b->{'meth'} } @Data; # swap $a and $b if you want the other direction print "Sorted:\n", Dumper( @Data ), "\n"; __DATA__ def,phyton\tjavascript,2 abc,perl\terlang\tlisp,1 ghi,arc\truby\tprolog,3

    also, avoid using $a and $b when not sorting. They will confuse you, because they are global. Not a problem in your code here though.
    hth

    Update: You had another question which I overlooked:
    the value you get, 2HASH(0x225e44), tells you that you have not a value, but a hash, which will have to be dereferenced to get at whatever is in the hash, for example using the keys function:

    my %dd; $dd{'1'}{'2'}{'3'}="hi"; $dd{'1'}{'3'}{'5'}="hello"; print "\nkeys in hash: ", join ' ', keys %{ $dd{'1'} };
      Thank you, you made my day!
Re: Sorting hash
by johngg (Canon) on Feb 21, 2008 at 11:53 UTC
    Firstly, you should avoid using the scalars $a and $b as they are special and are reserved for use with sort. Secondly, you should consider whether you want to remove the line terminator before doing your split; if you do, look at chomp.

    Remember that each element you are passing into the sort routine is a hash reference so you have to de-reference to get to the element you want to sort by. This should do what you want.

    my @Data = (); while ( <FH> ) { chomp; my ( $meth, $list, $count ) = split m{,}; push @Data, { meth => $meth, list => $list, count => $count, }; } @sortedData = sort { $a->{ meth } cmp $b->{ meth } } @Data;

    I hope this is useful.

    Cheers,

    JohnGG

Re: Sorting hash
by Punitha (Priest) on Feb 21, 2008 at 11:59 UTC

    Hi vsailas,

    You can try like this by modifying your array(@Data) to little bit as,

    use strict; my @Data; while(<DATA>){ chomp($_); my($string,$listref,$count)= split(',' , $_); push(@Data,[$string,$listref,$count]); } print "METH:$_->[0]\tREF:$_->[1]\tCOUN:$_->[2]\n" for sort {$a->[0] cm +p $b->[0]} @Data;


    __DATA__ meth2, \@array1, 3 meth3, \@array2, 36 meth1, \@array3, 8 meth5, \@array4, 10

    Punitha

Re: Sorting hash
by nikhil.patil (Sexton) on Feb 21, 2008 at 11:39 UTC
    You can use the Tie::Hash::Sorted module. This module presents hashes in sorted order.

    Alternatively, you can also use the Tie::IxHash module and add the elements into the hash in ascending order of $a. Tie::IxHash module implements hashes that preserve the order in which the hash elements were added into the hash.
      I think the thread title is misleading, the OP is actually trying to sort an array of hashes by one of the hash elements.

      Cheers,

      JohnGG

Re: Sorting hash
by hipowls (Curate) on Feb 21, 2008 at 19:37 UTC
    To answer your second question
    $dd{'1'}{'2'}{'3'}="hi";
    is equivalent to
    my %dd = ( 1 => { 2 => { 3 => 'hi' } } );
    and %{$dd{'1'}} is equal to ( 2 => { 3 => 'hi' } ). To get the value you assign it to a scalar and then dereference the keys of that hash ref.
    my $hash_ref1 = $dd{1}; print $hash_ref->{2}{3}, "\n"; # prints h1
    or if you are iterating over a structure
    while ( my ( $key, $hash_ref ) = each ( %{ $dd{1} } ) { # $key == 2 # $hash_ref == { 2 => { 3 => 'hi' } } }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (1)
As of 2024-04-25 00:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found