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

Hi, I had a simple comma-separated array (referenced), it looked like the following:
So after doing a foreach(sort @$outputRef), I set a breakpoint immediately after going in to the loop, and after printing it out it still came out as (unchanged):
Would anyone know why this didn't sort? So, just to clarify, this is what it was supposed to look like:

Replies are listed 'Best First'.
Re: Why didn't this sort?
by stephen (Priest) on Jul 15, 2002 at 23:19 UTC
    sort doesn't sort a list in-place. Instead, it returns a new sorted list. So:
    foreach (sort @$outputRef) { print $_, "\n"; }
    would print out a sorted list, but printing the contents of $outputRef would still print out an unsorted list.

    If you need to save the sorted list for some reason, use an assignment:

    @sorted = sort @$outputRef;


    Note: Code untested, my Perlboxen are still in pieces...
Re: Why didn't this sort?
by Ovid (Cardinal) on Jul 15, 2002 at 23:11 UTC

    The problem is that you need to sort on the element you want to sort on, not sorting the entire array. If you can explain your sort criteria that would help. Plus, where are you assigning your sort?

    I am just guessing, but let's say that you want to sort by the first item, alphabetically, and then the third item numerically. You could do this:

    my @sorted = sort { $a->[0] cmp $b->[0] || $a->[2] <=> $b->[2] } @$outputRef;

    If you give us a fuller code snippet with desired sort criteria, we can do better than speculate.


    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Why didn't this sort?
by thelenm (Vicar) on Jul 15, 2002 at 23:11 UTC
    If you're looking for the array @$outputRef itself to be sorted, you'll have to do something like this:
    $outputRef = [ sort @$outputRef ];
    When you say sort @$outputRef, you're creating an anonymous array with the sorted values, but not actually assigning the sorted values back into @$outputRef.

    -- Mike


      I know this is a minor thing, but it's probably best to make sure that you use the same reference instead of making a new one. If $ouputRef was pulled from a blessed object, for example, then this reassignment creates a new instance that isn't linked in.

      Assign back to the same reference just to be safe:
      @$outputRef = sort @$outputRef;
      These are "equivalent" in terms of functionality, but not in terms of effect. For an example of what I mean:
      my $foo = [ [ 4, 1, 6 ], [ 4, 1, 5 ] ]; my $foo_0 = $foo->[0]; my $foo_1 = $foo->[1]; $foo_0 = [ sort @$foo_0 ]; # $foo_0 is "detached" @$foo_1 = sort @$foo_1; # Goes back into $foo->[1] use Data::Dumper; print Dumper($foo);
Re: Why didn't this sort?
by jsprat (Curate) on Jul 15, 2002 at 23:18 UTC
    A guess (since you didn't include much code) - foreach is creating a sorted list of members of your array, not actually sorting your array. An example:

    @array=(2, 3, 1, 0); foreach (sort @array){ print "$_ - "; } print "\n"; print join " - ", @array; print "\n"; @array = sort @array; print join " - ", @array; __END__ Output: 0 - 1 - 2 - 3 - (printed in loop) 2 - 3 - 1 - 0 (after loop, still unsorted) 0 - 1 - 2 - 3 (after sorting, now sorted)

    Notice @a prints as if it is sorted in the loop, but after the loop it is still unsorted. If you want the array sorted, @array = sort @array; will work.