From: RichardOnRails Date: 2009-03-20T05:42:24+09:00 Subject: Re: Complex sort of matrix possible, e.g. like Excel? On Mar 18, 12:31 pm, Rob Biedenharn wrote: > 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 > > 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://agileconsultingllc.com > R...@AgileConsultingLLC.com On Mar 18, 12:31 pm, Rob Biedenharn wrote: > 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 > > 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://agileconsultingllc.com > R...@AgileConsultingLLC.com Hi Rob, Thanks for your response. I don't want to be an expert on sorting matrices. I just want to get my project working. (Don't we all :-) Here's the essence of what I've got working, confirmed with debugging puts'. matrix = [] FasterCSV.foreach(selectedCsvFile, :headers => false) do |row| matrix << row end I want (in Excel terms) the matrix sorted on column B asc. and within that col. I asc. Both columns are textual. Based on your guidance, I added the line: sortedMatrix = matrix.sort {|a,b| [a[1]<=>b[1], a[8] <=> b[8]]} Ruby gave me a syntax error: ProcessExports.rb:130:in `sort': undefined method `>' for [-1, 1]:Array (NoMethodError) I'm hoping the problem is that I'm invoking Array::Sort rather than Enumerable::Sort but nothing my deteriorating brain could devise worked. Any ideas. Best wishes, Richard