in reply to Re: Creating a hash from arrays
in thread Creating a hash from arrays

Thanks for all of the responses. Now I am trying to sort the resulting hash by values, not keys. Basically I need the array to be sorted alphabetically by state, not the people's name.

I know I can just call sort on the hash keys to sort the hash, but I can't get it to work if I call sort on values.

Replies are listed 'Best First'.
Re^3: Creating a hash from arrays
by BrowserUk (Patriarch) on Nov 02, 2013 at 22:58 UTC
    but I can't get it to work if I call sort on values.

    You need to create an array of the keys ordered by the associated values:

    [0] Perl> @a{ 1..26 } = reverse 'a'..'z';; @ordered = sort{ $a{$a} cmp $a{$b} } keys %a;; print "$_ :: $a{ $_ }" for @ordered;; 26 :: a 25 :: b 24 :: c 23 :: d 22 :: e 21 :: f 20 :: g 19 :: h 18 :: i 17 :: j 16 :: k 15 :: l 14 :: m 13 :: n 12 :: o 11 :: p 10 :: q 9 :: r 8 :: s 7 :: t 6 :: u 5 :: v 4 :: w 3 :: x 2 :: y 1 :: z

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      I still can't get it to sort by values. Sorting by keys seems to be easy, but it looks like values were not meant to be sorted by.

        Please show your code. (Update: And also take a look at BrowserUk's code. (Update: Oops... Just noticed your post was already a reply to BrowserUk's code post. Well, taking another look would not be wasted effort.))

        I still can't get it to sort by values. Sorting by keys seems to be easy, but it looks like values were not meant to be sorted by.

        No, absolutely not. Sorting by values is OK, as shown by examples above. If you don't get it right, then it means you are simply not doing right.

        This is an example built on the code proposed by Kenosis. I have changed and added a couple of names to make sure that the states don't get in the right order just by chance (which was the case with the original data you gave):

        use strict; use warnings; use Data::Dumper; my @fname = ( "Philip", "John", "Daniel", "John", "Ted" ); my @lname = ( "Johnson", "Hill", "Sharp", "Evans", "McCain" ); my @state = ( "AK", "CA", "AL", "WI", "TX"); my %hash = map { $fname[$_] . ' ' . $lname[$_] => $state[$_] } 0 .. $# +state; print "Unsorted:\n" ,Dumper \%hash; print "==========\n"; print "Sorted:\n", map "$_, $hash{$_}\n", sort {$hash{$a} cmp $hash{$b +}} keys %hash;
        which gives the following output:
        $ perl sort_hash.pl Unsorted: $VAR1 = { 'John Evans' => 'WI', 'Philip Johnson' => 'AK', 'John Hill' => 'CA', 'Ted McCain' => 'TX', 'Daniel Sharp' => 'AL' }; ========== Sorted: Philip Johnson, AK Daniel Sharp, AL John Hill, CA Ted McCain, TX John Evans, WI
        As you can see, the data is now sorted by the values (i.e. the State).

        If you still don't succeed to do it, please show your code.

Re^3: Creating a hash from arrays
by marinersk (Priest) on Nov 03, 2013 at 01:31 UTC
    Sorting based on values rather than keys suggests you built your hash backwards -- or, if you need both directions, then perhaps you should consider a reverse lookup. BrowserUK suggests an array; another hash would not necessarily be out of the question. It would likely need to be a hash of arrays, however.

    my %personInfo = (); my %stateInfo = (); while (###) # loop through data { $personInfo{$name} = $state; push @{$stateInfo{$state}}, $name; }

    Now you can look up in either direction.

Re^3: Creating a hash from arrays
by AnomalousMonk (Archbishop) on Nov 02, 2013 at 22:42 UTC
      This is what I was doing (copied from another site):
      my ($i, $j); foreach my $value (sort {$statefinal{$i} cmp $statefinal{$j}} keys %st +atefinal) { print "$value $statefinal{$value}\n"; }

      That code was suppose to sort by values, but I'm just getting a lot of uninitialized values errors when I run it. It's not sorting by values (states).

        $i and $j have no meaning (Update: and are given no value; i.e., are uninitialized) in your comparison expression (see sort). Try something like:

        foreach my $fn_ln (sort { $statefinal{$a} cmp $statefinal{$b} } keys % +statefinal) { print qq{'$fn_ln' in $statefinal{$fn_ln}}; }

        Update: NB: This sorts the keys (first/last name) by their values (states) in lexic-ascending order.

        You're using $value as key?

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        That code was suppose to sort by values
        You're nearly there...
        my %hash; for my $i (0 .. $#fname) { $hash{ "$fname[$i] $lname[$i]" } = $state[$i] } # sort the keys by value for my $key ( sort { $hash{$a} cmp $hash{$b} } keys %hash ) { print "$key $hash{$key}\n"; } # alternatively my @sorted = sort { $hash{$a} cmp $hash{$b} } keys %hash; for my $key ( @sorted ) { print "$key $hash{$key}\n"; }
        $a and $b are special variables and are not the same as $i and $j in your example... see sort