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

Wow that worked great. Thanks.
Now what if the array is:
my @id = ('001=0,2', '010=3', '014=0,0', '060=4', '071-1=3');
And I want to sort the same way but ignoring the '=' sign and anything after.

Replies are listed 'Best First'.
Re^3: How do I sort an array by hash value?
by ikegami (Patriarch) on Aug 17, 2009 at 21: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;