Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

how to sort multi-dimensional arrays

by Anonymous Monk
on Mar 24, 2004 at 05:19 UTC ( [id://339301]=perlquestion: print w/replies, xml ) Need Help??

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

I have the following code snippet which should sort the the @x array on the 2nd element of $x[], but instead it dies with the following message.
Modification of a read-only value attempted at a.pl line 8.
---------------------
#!/usr/bin/perl -w $x[1][1]=11; $x[1][2]=12; $x[1][3]=13; $x[2][1]=21; $x[2][2]=22; $x[2][3]=23; @sorted = sort {$b->[2]cmp $a->[2] } @x;
--------------------------

Debugging revealed that I can access $b->[2] ok but whenever I attempt to dereference the $a variable it dies as above. The same thing happens if I use the  $$a[2] syntax instead of $a->{2]. Any perls of wisdom would be much appreciated.

Edit by tye, remove PRE tags

Replies are listed 'Best First'.
Re: how to sort multi-dimensional arrays
by Zaxo (Archbishop) on Mar 24, 2004 at 05:56 UTC

    You can avoid this kind of error by just treating the arrays as ordered data structures:

    my @x = ( [ 11, 12, 13], [ 21, 22, 23] ); my @sorted = sort { $b->[1] <=> $a->[1] } @x;
    I modified the index in the comparison to suit zero-base, and made the comparison operator numeric.

    After Compline,
    Zaxo

Re: how to sort multi-dimensional arrays
by kvale (Monsignor) on Mar 24, 2004 at 05:31 UTC
    Your problem is that @x has indices in the range (0..2), but $x[0][2] is not defined. Dereferencing an undefined element causes the error.

    Update: fixed the range above.

    -Mark

Re: how to sort multi-dimensional arrays
by kappa (Chaplain) on Mar 24, 2004 at 11:01 UTC
    Arrays in Perl are zero-based (generally). Look, you initialize array starting from index 1 and that means you totally leave out the first row and the first column in each of the subsequent rows.

    Then sort starts to iterate on rows of your array and access their third (->[2]) element. This of course fails, as your first row is undef.

    Use your Perl arrays with zero-based indices as was intended by design :)

      This brings up the tired joke of the computer science professor who walks in with five #2 pencils for his five students taking a test.

      The student says "Good, I see you have brought five pencils in for us!"

      The professor scratches his head and looks confused. "Surely you can't be taking Numerical Methods without the ability to count, son! There are four pencils! 0, 1, 2, 3, 4!"

      ---

      To the OP: Bottom line, not just Perl, but all of computer science and computers in general, are zero based. After all, arrays (in C) are just offsets to memory addresses, and [0] means no offset, [1] means one width further on, and this means essentially arrays are pointer arithmetic. Now, this doesn't directly apply to Perl (at least not on the surface), but this is why we have zero-basing as a standard.

      To be honest though, I don't think the notion of sorting a two dimensional array makes sense, and the lists of arrays suggestion (while not syntactically cleaner) seems to be what you want. If you really want something more advanced, maybe, just maybe, PDL might be worth looking at. It could (as far as I know) "sort" N-th dimensional arrays by arbitrary columns without blinking.

        To use PDL for this, you'd use qsorti on a slice to get the relevant column, then dice_axis the original structure on the sorted indices.
        Pascal lessons do a good (for some unusual values of "good") job of teaching people to abuse arrays. I remember, we always used 1-based arrays as they were "more natural". Teacher said so.
      Psst, hey, buddy. $[ = 1; (perlvar). I was never here.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://339301]
Approved by Paladin
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (3)
As of 2024-04-25 10:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found