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

Hi all ,
I've the following hash . and how can i sort

Code:

my @ar = ("Z","B","A"); my %x = ('period' => "2010/05", 'type' => "voice", 'tcon' => "A,B", 'hcon' => "@arr" );
In the above i want to sort 'hcon'.
How can i do that??

Replies are listed 'Best First'.
Re: Sorting the hash
by dasgar (Priest) on Oct 04, 2010 at 10:21 UTC

    First, please put your code in <c></c> tags.

    I didn't test the code below, but it should do the trick. It probably isn't very efficient or elegant, but it does illustrate each logical step. I'm sure others will be able to do it with fewer lines of code.

    use strict; use warnings; use Data::Dumper; my %x = ('period' => "2010/05", 'type' => "voice", 'tcon' => "A,B", 'h +con' => "Z,T,A" ); # extract out the value, which is a string my $string = $x{'hcon'}; # split the string my (@array) = split /,/,$string; # sort the elements my (@sorted) = sort @array; # recreate string with sorted elements my $new_string = join (",",@sorted); # store back into the hash $x{'hcon'} = $new_string; print Dumper($x);

      If @arr is really supposed to be @ar, then it might be better to use $" (aka $LIST_SEPARATOR) to split and regenerate the string representing the array in the hash element that is to be sorted. It is the value of this special or predefined variable (see perlvar) that is used as a separator string when interpolating an array into a string in the first place.

      Leaving out some of the intermediate, illustrative steps (qq{} is used instead of "" for double-quoting just to avoid the appearance of a bunch of \ escapes in the example code):

      >perl -wMstrict -le "use English; use Data::Dumper; ; my @arr = ('Z', 'B', 'A'); my %x = ( period => '2010/05', typ => 'voice', tcon => 'A,B', hcon => qq{@arr}, ); ; print qq{hcon '$x{hcon}'}; ; my @array = split /\Q$LIST_SEPARATOR/, $x{hcon}; @array = sort @array; ; $x{hcon} = qq{@array}; ; print Dumper \%x; " hcon 'Z B A' $VAR1 = { 'tcon' => 'A,B', 'period' => '2010/05', 'hcon' => 'A B Z', 'typ' => 'voice' };

      Update: Added metaquoting to  split regex per tinita's suggestion. Also: using English version of $" to avoid any confusion introduced by Windoze command line escaping of " character.

        well, in that case, if you really want to be safe, you should split on quotemeta $" since $" could be a special regex character like | or *
        ;-)
      Thank you for giving answer. But i'm getting the following err. Global symbol "$x" requires explicit package name at D:\Perl\quote_1.pl line 24
        Which is why we use strict, the line should read
        print Dumper(\%x);
        And by using stricture the error was highlighted rather than causing you to puzzle out why there was no returned values.

        print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."

        That line should be:

        print Dumper(\%x);

        Instead of:

        print Dumper($x);

        Since you could have a hash, %x, and a completely unrelated scalar, $x, in the same scope.

        Thanks dasgar.. Now i got it Thank you so much
Re: Sorting the hash
by Marshall (Canon) on Oct 04, 2010 at 17:16 UTC
    Perhaps this changes the problem statement a bit, and it takes us into some more advanced topics, but 'hcon' => "@arr" makes a string out of @ar. A hash key can only have a single value, in this case a string is used. But it is possible to put a reference to an array in the hash as that single value instead of converting the array to a string.

    The syntax for this can be a bit daunting. If you work often with structures like this you might want to start by reading perlreftut.

    Below, 'hcon' => [@ar] the square brackets say: allocate some new memory for an array and copy @ar into that memory. Then assign a reference to that new memory to the key, 'hcon'.

    De-referencing the array looks like: @{$x{'hcon'}}. By preserving the array nature of @ar, the sort is a lot easier, actually just one line as shown below.

    I think I got too complex here, but I thought you might want to see an example of what is possible as your Perl journey continues.

    #!/usr/bin/perl -w use strict; use Data::Dumper; my @ar = ("Z","B","A"); my %x = ('period' => "2010/05", 'type' => "voice", 'tcon' => "A,B" , 'hcon' => [@ar] ); print Dumper \%x; @{$x{'hcon'}} = sort @{$x{'hcon'}}; print Dumper \%x;