in reply to Re^2: How would I sort a two-dimensional array by multiple columns?
in thread How would I sort a two-dimensional array by multiple columns?

Yes, you're right. I'll update the node now.

Thanks

Replies are listed 'Best First'.
Re^4: How would I sort a two-dimensional array by multiple columns?
by NetWallah (Canon) on Mar 15, 2008 at 22:01 UTC
    There are subtle bugsdifferences in interpretation of the OP's request in both jettero and FunkyMonk's solutions.

    In essence, neither goes deep enough to resolve differences - jettero stops at the second element, and FunkyMonk stops after index 3.

    FunkyMonk - in your code, "@_" inside the sort is probably not what you think it is - at that point, @_ is still the parameter passed into "sortsub". Inside the sort itself, you only have $a and $b. The "@_" comes from the outer sub.

    Here is code with slightly modified data, that demonstrates the errors, and my proposed "correct" solution.

    Update: Updated based on ikegami's note below (return 0, not 1);
    Also updated FonkyMonk's sort - uses @_ instead of 0..@_.

    Update 2: The O.P. has correctly chosen Funkymonk's code as representing what he requested.
    My code addresses a different issue - sorting to the complete depth.

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

      While I like your solution, FunkyMonk's routine could be made to sort on all elements of an array by changing its arguments:

      my $sorted = FunkyMonkSort($unsorted, 0..$#$unsorted);

      Your code meets the specification to sort a 2D array where each element in every row is compared.

      FunkyMonk's code solves a different problem--sort a 2D array by an arbitrary subset of elements in each row.

      I spent a while looking for the "bug". There really isn't a bug, it's just that you interpreting the spec differently than FunkyMonk did.

      BTW, I like the way that you called attention the the fact the NetWallaSort() is a sort function, and gets $a and $b automagically.


      TGI says moo

        TGI (++)- Agreed to all your points.

        I had /msg'd FunkyMonk (also ++) that I had misread the OP's requirement.

        I now publicly post that his post was NOT buggy, based on what the OP said he wanted, and his "@_" was indeed what he intended (after his update).

             "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

      The sort I wrote was written to match the OP's spec: to sort by columns 1, 2 then 4 (which I took to mean 0, 1 and 3 in Perl terms)

      Note that I updated my node a couple of hours before you posted :(

      FunkyMonk - in your code, "@_" inside the sort is probably not what you think it is - at that point, @_ is still the parameter passed into "sortsub". Inside the sort itself, you only have $a and $b. The "@_" comes from the outer sub.
      That's exactly what I intended

      update: much less than a couple of hours:(

      I think
      return 1; #Pathological
      should be
      return 0; #Pathological
      $a and $b are equal at that point, so zero should be returned.

      I think some versions of sort in some versions of Perl even crashe when inconsistent results (a < b < a) are returned, something that can happen when returning non-zero for equal values.

      NetWallah, That went abit over my head. So how would your code look like?

      I am not clear on how I would implement this to

      input:

      @toBeSorted, 0, 1, 3)

      output:

      @sorted

      Can I see what you code would look like so that I can study the correct way?


      After all this is over, all that will really have mattered is how we treated each other.
        The only relevant part of the code I posted is "sub NetWallahSort".

        Just copy that sub into your code, and use it like:

        my @sorted = sort NetWallahSort @$unsorted; # Or, simply "@unsorted", if @unsorted is an Array-of-Arrays, # rather than a reference.
        FYI - a 2-Dimensional array is technically an "Array of Array-references".

        FonkyMonk makes his declaration ($unsorted) a scalar, which is a "reference to an Array of Array-references", or "a reference to a 2-d Array". As Sienfeld would say - not that there is anything wrong with that!

             "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom