[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Complex sort of matrix possible, e.g. like Excel?

RichardOnRails

3/18/2009 5:02:00 AM

Hi,

I've got an array of rows (and thus a matrix) created user FasterCSV
to extract data from a CSV file. I'd like to sort the matrix on
column A ascending and, within that, column B descending. I looked at
Matrix, but it doesn't seem to address that functionality. Is there
a package that does, or do I have to write my own SuperMatrix
inherited from Matrix?

Thanks in Advance,
Richard
13 Answers

Christopher Dicely

3/18/2009 5:58:00 AM

0

Enumerable#sort lets you do this fairly easily with just a pure array
of arrays, e.g., to sort the array-of-arrays "arr" by the first column
ascending and the second descending:

arr.sort {|a,b| [a[0]<=>b[0], b[1]<=>a[1]].find {|x| x!=0} || 0}



On 3/17/09, RichardOnRails <RichardDummyMailbox58407@uscomputergurus.com> wrote:
> Hi,
>
> I've got an array of rows (and thus a matrix) created user FasterCSV
> to extract data from a CSV file. I'd like to sort the matrix on
> column A ascending and, within that, column B descending. I looked at
> Matrix, but it doesn't seem to address that functionality. Is there
> a package that does, or do I have to write my own SuperMatrix
> inherited from Matrix?
>
> Thanks in Advance,
> Richard
>
>

Robert Klemme

3/18/2009 10:17:00 AM

0

2009/3/18 Christopher Dicely <cmdicely@gmail.com>:
> Enumerable#sort lets you do this fairly easily with just a pure array
> of arrays, e.g., to sort the array-of-arrays "arr" by the first column
> ascending and the second descending:
>
> arr.sort {|a,b| [a[0]<=>b[0], b[1]<=>a[1]].find {|x| x!=0} || 0}

Alternatively with less intermediate Arrays and less comparison operations.

arr.sort do |a,b|
c = a[0]<=>b[0]
c == 0 ? b[1]<=>a[1] : c
end

You can as well do

arr.sort_by {|a,b| [a[0]<=>b[0], b[1]<=>a[1]]}

Cheers

robert



--
remember.guy do |as, often| as.you_can - without end

RichardOnRails

3/18/2009 2:23:00 PM

0

On Mar 18, 1:58 am, Christopher Dicely <cmdic...@gmail.com> wrote:
> Enumerable#sort lets you do this fairly easily with just a pure array
> of arrays, e.g., to sort the array-of-arrays "arr" by the first column
> ascending and the second descending:
>
> arr.sort {|a,b| [a[0]<=>b[0], b[1]<=>a[1]].find {|x| x!=0} || 0}
>
> On 3/17/09, RichardOnRails <RichardDummyMailbox58...@uscomputergurus.com> wrote:
>
> > Hi,
>
> > I've got an array of rows (and thus a matrix) created user FasterCSV
> > to extract data from a CSV file.  I'd like to sort the matrix on
> > column A ascending and, within that, column B descending.  I looked at
> > Matrix,  but it doesn't seem to address that functionality.  Is there
> > a package that does, or do I have to write my own SuperMatrix
> > inherited from Matrix?
>
> > Thanks in Advance,
> > Richard
>
>

Hey Christopher,

That's perfect! I had faith that the community had dealt with this
issue.

Best wishes,
Richard

RichardOnRails

3/18/2009 2:24:00 PM

0

On Mar 18, 6:16 am, Robert Klemme <shortcut...@googlemail.com> wrote:
> 2009/3/18 Christopher Dicely <cmdic...@gmail.com>:
>
> > Enumerable#sort lets you do this fairly easily with just a pure array
> > of arrays, e.g., to sort the array-of-arrays "arr" by the first column
> > ascending and the second descending:
>
> > arr.sort {|a,b| [a[0]<=>b[0], b[1]<=>a[1]].find {|x| x!=0} || 0}
>
> Alternatively with less intermediate Arrays and less comparison operations.
>
> arr.sort do |a,b|
>  c = a[0]<=>b[0]
>  c == 0 ? b[1]<=>a[1] : c
> end
>
> You can as well do
>
> arr.sort_by {|a,b| [a[0]<=>b[0], b[1]<=>a[1]]}
>
> Cheers
>
> robert
>
> --
> remember.guy do |as, often| as.you_can - without end

Hi Robert,

As usual, you've got the perfect answer. Thank you very much.

Best wishes,
Richard

Gary Wright

3/18/2009 3:38:00 PM

0


On Mar 18, 2009, at 6:16 AM, Robert Klemme wrote:
> You can as well do
>
> arr.sort_by {|a,b| [a[0]<=>b[0], b[1]<=>a[1]]}

This doesn't seem quite right to me. Shouldn't it be:

arr.sort_by { |item| [item[0], item[1]] }

sort_by will use Array#<=> to compare the two element
array and Array#<=> simply uses <=> on each element.

Gary Wright

Robert Klemme

3/18/2009 3:59:00 PM

0

2009/3/18 Gary Wright <gwtmp01@mac.com>:
>
> On Mar 18, 2009, at 6:16 AM, Robert Klemme wrote:
>>
>> You can as well do
>>
>> arr.sort_by {|a,b| [a[0]<=3D>b[0], b[1]<=3D>a[1]]}
>
> This doesn't seem quite right to me. =A0Shouldn't it be:
>
> arr.sort_by { |item| [item[0], item[1]] }

Yes, you're right. Copy & paste error. However, your solution is not
fully correct either because it does not take into consideration that
order of the second column should be reversed. So you'd have to do

arr.sort_by { |item| [item[0], -item[1]] }

Thanks for the heads up!

robert

--=20
remember.guy do |as, often| as.you_can - without end

Rob Biedenharn

3/18/2009 4:31:00 PM

0

On Mar 18, 2009, at 1:58 AM, Christopher Dicely wrote:

> Enumerable#sort lets you do this fairly easily with just a pure array
> of arrays, e.g., to sort the array-of-arrays "arr" by the first column
> ascending and the second descending:
>
> arr.sort {|a,b| [a[0]<=>b[0], b[1]<=>a[1]].find {|x| x!=0} || 0}

Not to detract to much from the other responses, but this ought to be:

arr.sort {|a,b| (a[0] <=> b[0]).nonzero? || b[1] <=> a[1] }

Take a look at what Numeric#nonzero? does. The docs specifically
mention its use when chaining comparisons this way.

Doing arr.sort_by {|a| [a[0], -a[1]] } only works if the second
element responds to @- (like any Numeric would, but certainly not
String).

-Rob

> On 3/17/09, RichardOnRails <RichardDummyMailbox58407@uscomputergurus.com
> > wrote:
>> Hi,
>>
>> I've got an array of rows (and thus a matrix) created user FasterCSV
>> to extract data from a CSV file. I'd like to sort the matrix on
>> column A ascending and, within that, column B descending. I looked
>> at
>> Matrix, but it doesn't seem to address that functionality. Is there
>> a package that does, or do I have to write my own SuperMatrix
>> inherited from Matrix?
>>
>> Thanks in Advance,
>> Richard

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com

Rob Biedenharn

3/20/2009 2:05:00 AM

0


On Mar 19, 2009, at 9:22 PM, RichardOnRails wrote:

> OK Rob,
>
> I Googled "Ruby nonzero? (thus doing essentially what you suggest in
> your original response). And I see that when the expression is
> processed by nonzero?, the latter returns NOT true or false, but
> rather non-zero value or nil (which is almost 'false'). Cool!
>
> So my extra "v" is documented to be superfluous :-)
>
> Again, many thanks for your generous and excellent guidance.
>
> Best wishes,
> Richard


Richard,

Glad to have helped.

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com



Ryan Davis

3/20/2009 2:44:00 AM

0


On Mar 17, 2009, at 22:02 , RichardOnRails wrote:

> I've got an array of rows (and thus a matrix) created user FasterCSV
> to extract data from a CSV file. I'd like to sort the matrix on
> column A ascending and, within that, column B descending. I looked at
> Matrix, but it doesn't seem to address that functionality. Is there
> a package that does, or do I have to write my own SuperMatrix
> inherited from Matrix?

I'm kinda surprised nobody has said this:

sorted = matrix.sort_by { |row| [row[0], -row[1]] }

P.S. PLEASE trim to the relevant parts when you reply. In some of your
email on this thread you have two whole copies of nearly the whole
thread.


Rob Biedenharn

3/20/2009 3:02:00 AM

0

On Mar 19, 2009, at 10:44 PM, Ryan Davis wrote:
> On Mar 17, 2009, at 22:02 , RichardOnRails wrote:
>
>> I've got an array of rows (and thus a matrix) created user FasterCSV
>> to extract data from a CSV file. I'd like to sort the matrix on
>> column A ascending and, within that, column B descending. I looked
>> at
>> Matrix, but it doesn't seem to address that functionality. Is there
>> a package that does, or do I have to write my own SuperMatrix
>> inherited from Matrix?
>
> I'm kinda surprised nobody has said this:
>
> sorted = matrix.sort_by { |row| [row[0], -row[1]] }
>
> P.S. PLEASE trim to the relevant parts when you reply. In some of
> your email on this thread you have two whole copies of nearly the
> whole thread.


Actually, it was suggested, but it assumes that row[1] has a -@
method. The OP confirmed later that the columns are text, not numbers.

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com