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

If I have a two-dimensional array, what's the easiest way to sort it first on one column and then those results on a second column? I've tried using the Data::Table module, but I apparently keep erring on syntax.

Original (2 x 4) values:

Mary 3

John 2

John 4

Mary 7

Desired values, sorting first on name, then on number:

John 2

John 4

Mary 2

Mary 7

Thanks, cypress

  • Comment on sorting on multiple columns using Data::Table?

Replies are listed 'Best First'.
Re: sorting on multiple columns using Data::Table?
by olus (Curate) on Feb 25, 2008 at 18:45 UTC

    Please show us how you have tried so far using Data::Table, so that we may try to point your eventual syntax errors.

      use Data::Table; $header[0] = "NAME"; $header[1] = "NUMBER"; $data[0][0] = "Mary"; $data[0][1] = 3; $data[1][0] = "John"; $data[1][1] = 2; $data[2][0] = "John"; $data[2][0] = 4; $data[3][0] = "Mary"; $data[3][1] = 2; $table = new Data::Table ($data, $header, 0); # TRIPLETS, FIRST PARAM IS COLUMN INDEX, SECOND IS NUMERICAL VALUE/ # NON-NUMERICAL, THIRD IS ASCENDING/DESCENDING SORT $table->sort(0, 1, 0, 1, 0, 0); # RECONSTITUTE ARRAY $data[0][0] = $table->elm(0,0); $data[0][1] = $table->elm(0,1); $data[1][0] = $table->elm(1,0); $data[1][1] = $table->elm(1,1); $data[2][0] = $table->elm(2,0); $data[2][1] = $table->elm(2,1); $data[3][0] = $table->elm(3,0); $data[3][1] = $table->elm(3,1); print "$header[0]\t$header[1]\n\n"; print "$data[0][0]\t$data[0][1]\n"; print "$data[1][0]\t$data[1][1]\n"; print "$data[2][0]\t$data[2][1]\n"; print "$data[3][0]\t$data[3][1]\n";
      Running it, I get the error message: Row index out of range 0..-1

      Thanks again, cypress

      (And I did make a slight data typo in my original post.)

        You should start by using strict and warnings. And if you did, you might have spotted this. Note that you are assigning values to elements of the array @data and the constructing the object Data::Table with the scalar $data which does not relate to the array, and it is not the array reference the constructor is expecting. The same applies to @header.

Re: sorting on multiple columns using Data::Table?
by apl (Monsignor) on Feb 25, 2008 at 19:29 UTC
    When you say two-dimensional array, do you actually mean a Hash of Hashes? That is, are you sorting on values ( $value[1][0] = 'John 3') or keys ( $value{John}{3} )?

    Revised: (as the code was just posted)

    You should consider using a Hash instead, if you know that each Name will never have more than one entry with the same Number value. Much easier to sort...

      Two dim array, although perhaps I could consider using a hash of hashes.
Re: sorting on multiple columns using Data::Table?
by cypress (Beadle) on Feb 25, 2008 at 19:35 UTC
    Two dim array, although perhaps I could consider using a hash of hashes.
Re: sorting on multiple columns using Data::Table?
by cypress (Beadle) on Feb 25, 2008 at 19:40 UTC
    Unfortunately, apl, I can't guarentee that....
Re: sorting on multiple columns using Data::Table?
by cypress (Beadle) on Feb 25, 2008 at 19:46 UTC
    In fact, what I have is a multi-dim database which I'd like to sort by several fields. Is there a Perl module for sorting databases by multiple fields? Thanks.
      Perhaps you should start by listing the various fields in the record, which you wish to sort on, which are unique, etc.

      Or, if there ar enough records, you could consider sticking the information in a Sybase table, and let it worry about the sorting.

      The best way to sort data from a database is to let the database do the sorting.

      Anyway, there are several modules from CPAN that allow to create multifield sorters on the fly as for instance Sort::Key/Sort::Key::Maker and Sort::Maker.