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

This seems like such a no brainer ... but I can't wrap my mind around it.

# say I've got a two dimensional array... @a = ( ["oops", 0], [ "happy", 2 ], [ "word", 4 ] ); # and I wanna print the contents of it thusly: foreach $ar (@a) { print "$ar->[0] is $ar->[1]\n" } # how would I sort the @a based on the $ar->[0]?

Replies are listed 'Best First'.
Re: sort my arrayref
by Trimbach (Curate) on Dec 12, 2000 at 18:33 UTC
    You can do this by using the special $a and $b variables with sort. Like so:
    @a = ( ["oops", 0], [ "happy", 2 ], [ "word", 4 ] ); foreach $ar(sort {$a->[0] cmp $b->[0]} @a) { print "$ar->[0] is $ar->[1]\n"; }
    The way I remember how to do this is to think that sort can use an optional code block with $a and $b... $a and $b are automagically populated the same way that (in this case) $ar is populated, and they're populated with the same kind of data that $ar is, again, in this case a reference to an anonymous array. By de-referencing $a and $b to the parts you want to sort by you get the kind of sort you want. If you wanted to sort by the second element in each anonymous array, use $a->[1] cmp $b->[1] instead.

    Gary Blackburn
    Trained Killer

More sort Info
by c-era (Curate) on Dec 12, 2000 at 19:39 UTC
    Sort is very powerful and customizable. With sort you can create your own sub routine to determine how an array is sorted. Your subroutine will get two elements of your array as $a and $b. Your return code will determine how the array will be sorted.
    -1 -- $a comes before $b
    0 -- $a and $b are equal
    1 -- $b comes before $a
    Below is an example of how to sort on two keys:
    @a = ( ["oops", 1], ["oops", 0], [ "happy", 2 ], [ "word", 4 ] ); @a = sort my_sort @a; foreach $ar (@a) { print "$ar->[0] is $ar->[1]\n" } sub my_sort { # Lets first compare element 0 if ($a->[0] lt $b->[0]){ return -1; } if ($a->[0] gt $b->[0]){ return 1; } # Element 0 is equal, let now compare element 1 if ($a->[1] < $b->[1]){ return -1; } if ($a->[1] > $b->[1]){ return 1; } # Both elements are equal return 0; }
    Note, this code is not necessarily the best way to do this, it is provided to show some theory behind sort.
Re: sort my arrayref
by mrmick (Curate) on Dec 12, 2000 at 18:43 UTC
    This is one of the sorting routines I had to learn the hard way. You simply have to choose which sub-element by which you'll do the sorting in your sort statement and then you're home free.
    # say I've got a two dimensional array... @array = ( ["oops", 0], [ "happy", 2 ], [ "word", 4 ] ); # sort on the sub-element of your choice here.... @sorted = sort{$a->[0] cmp $b->[0]}@array; # and I wanna print the contents of it thusly: foreach $ar (@sorted) { print "$ar->[0] is $ar->[1]\n" } # how would I sort the @a based on the $ar->[0]?

    Mick
Why not use a hash?
by tedv (Pilgrim) on Dec 12, 2000 at 21:56 UTC
    From the example data, you might be better off with a hash. It's much, much easier to manipulate (oops => 0, happy => 2, word => 4) than crazy array accessing. On top of that, it's clear you don't care about the original order of the array because you're sorting it. The only reason you might not be able to use an array is if you want to have duplicate entries (like [happy, 2], [happy, 2], or [oops, 0], [happy, 0], [happy, 2]. The second one doesn't have any true duplicates, but it's constructed in a way that you can't use either the left or the right element for the hash keys. But I doubt this is the case. Determine which value you will more commonly use for access (probably the number) and use it for hash keys.

    -Ted