in reply to Re^2: How do I sort an array by hash value?
in thread How do I sort an array by hash value?

@id = sort { ( my $a_ = $a ) =~ s/=.*//s; ( my $b_ = $b ) =~ s/=.*//s; $lid->{$a_} cmp $lid->{$b_} } @id;

Update: Oops, added missing underscores as per Re^5: How do I sort an array by hash value?

Replies are listed 'Best First'.
Re^4: How do I sort an array by hash value?
by josh097 (Initiate) on Aug 17, 2009 at 22:02 UTC
    Thanks. I really appreciate your help.
    Here is how I failed:
    @id = sort { $lid->{split(/=/, $a)} cmp $lid->{split(/=/, $b)} } @id;
    Your approach doesn't seem to sort the array unless I change it from
    my $a_ = $a my $b_ = $b
    to
    $a = $a $b = $b
    But if I do that then the values of the array get cut off at the '=' sign (I understand why).
    What does the 'my $a_ = $a' do?
      It should be as ikegami had it, except the
          $lid->{$a} cmp $lid->{$b}
      statement should be
          $lid->{$a_} cmp $lid->{$b_}
      (note addition of the trailing underscores).

      The  my $a_ = $a; step is so the values in the array aliased by the 'magical' variables  $a and  $b are not changed by the substitutions (i.e., the change you noted).

      @id = sort { $lid->{split(/=/, $a)} cmp $lid->{split(/=/, $b)} } @id;

      What does split return in scalar context...

      Here is how I failed:
      @id = sort { $lid->{split(/=/, $a)} cmp $lid->{split(/=/, $b)} } @id;

      Near to success:

      @id = sort { $lid->{(split(/=/, $a))[0]} cmp $lid->{(split(/=/, $b))[0 +]} } @id;

      This line has to evaluate $a and $b each time sort does a comparison, which isn't efficient. I guess that ikegami's line neither is.

      Should be used a temporary translation hash? Something like:

      my %temp = map { $_ => (split(/=/, $_, 2))[0] } @id; @id = sort { $lid->{$temp{$a}} cmp $lid->{$temp{$b}} } @id;