Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > sort double-dimensional array by column

Reply
Thread Tools

sort double-dimensional array by column

 
 
Mr_Tibs
Guest
Posts: n/a
 
      10-12-2007
Hi,

I have a [m X n] double-dimensional array in Ruby and I'm trying to
sort the entries (rows) by the 6-th column, which is a DateTime
object. Things get a little bit complicated, since I might have a nil
value in that column. If that happens, then I want to sort by the 7-th
column.
This is what I have so far:

cset_arr = cset_arr.sort do |x, y|
if x[5].nil? && y[5].nil?
x[6] <=> y[6]
elsif x[5].nil? && !y[5].nil?
y[5] # ???
elsif !x[5].nil? && y[5].nil?
x[5] # ???
elsif !x[5].nil? && !y[5].nil?
x[5] <=> y[5]
end
end

For the second and third if statements, I don't know how to "select"
that value. So, for example, if both 6-th columns are nil, then
compare by the 7-th column (first if). But, if the first record has a
nil 6-th column and the second record has a non-nil 6-th column, then
how do I set the second record as being the "selected" one of the two?
The current form (e.g. y[5]) does not work.

Thanks,
Tiberiu

 
Reply With Quote
 
 
 
 
John Woods
Guest
Posts: n/a
 
      10-12-2007

If I understand what you're after, I'd say in the 2nd & 3rd conditions,
you'd want to always treat nil as being less than a non-nil value. So
always return -1 and 1 respectively. As an aside, you can get rid of the
!x.nil? checks because the previous conditions assure that state...

cset_arr = cset_arr.sort do |x, y|
if x[5].nil? && y[5].nil?
x[6] <=> y[6]
elsif x[5].nil?
-1
elsif y[5].nil?
1
else
x[5] <=> y[5]
end
end


-----Original Message-----
From: Mr_Tibs
Sent: 10/11/2007 07:15 PM
> Hi,
>
> I have a [m X n] double-dimensional array in Ruby and I'm trying to
> sort the entries (rows) by the 6-th column, which is a DateTime
> object. Things get a little bit complicated, since I might have a nil
> value in that column. If that happens, then I want to sort by the 7-th
> column.
> This is what I have so far:
>
> cset_arr = cset_arr.sort do |x, y|
> if x[5].nil? && y[5].nil?
> x[6] <=> y[6]
> elsif x[5].nil? && !y[5].nil?
> y[5] # ???
> elsif !x[5].nil? && y[5].nil?
> x[5] # ???
> elsif !x[5].nil? && !y[5].nil?
> x[5] <=> y[5]
> end
> end
>
> For the second and third if statements, I don't know how to "select"
> that value. So, for example, if both 6-th columns are nil, then
> compare by the 7-th column (first if). But, if the first record has a
> nil 6-th column and the second record has a non-nil 6-th column, then
> how do I set the second record as being the "selected" one of the two?
> The current form (e.g. y[5]) does not work.
>
> Thanks,
> Tiberiu
>
>
>
>


 
Reply With Quote
 
 
 
 
mortee
Guest
Posts: n/a
 
      10-12-2007
Mr_Tibs wrote:
> Hi,
>
> I have a [m X n] double-dimensional array in Ruby and I'm trying to
> sort the entries (rows) by the 6-th column, which is a DateTime
> object. Things get a little bit complicated, since I might have a nil
> value in that column. If that happens, then I want to sort by the 7-th
> column.
> This is what I have so far:
>
> cset_arr = cset_arr.sort do |x, y|
> if x[5].nil? && y[5].nil?
> x[6] <=> y[6]
> elsif x[5].nil? && !y[5].nil?
> y[5] # ???
> elsif !x[5].nil? && y[5].nil?
> x[5] # ???
> elsif !x[5].nil? && !y[5].nil?
> x[5] <=> y[5]
> end
> end


What about this one?

cset_arr.sort_by{|row| [ row[5] || DateTime.new, row[6] ] }

Comparing two arrays returns the comparison of the first differing pair
of respective elements. DateTime.new returns some value far in the past,
I guess the lowest possible value. So if both dates are nil, then the
first value in the sort key become the same (this default DateTime
value), thus the 7th column gets compared. Otherwise nil gets replaced
by a value which is most probably lower than any meaningful one.

mortee


 
Reply With Quote
 
Mr_Tibs
Guest
Posts: n/a
 
      10-12-2007
Hi James,

Thanks for the reply. It was what I needed (with a small correction:
inverse -1 and 1). I didn't read the Array.sort doc properly and
didn't know what I supposed to return.

Thanks,
Tiberiu

 
Reply With Quote
 
Mr_Tibs
Guest
Posts: n/a
 
      10-12-2007
Thanks mortee. That sort of worked. Unfortunately, it puts those
entries that have the 6-th column = nil, at the start of the sorted
array (instead of at the end). I don't really understand the technique
used. You are sorting by row, but you are somehow defining and using
an array with 2 elements (that's what the square brackets do, right?).

Tiberiu

 
Reply With Quote
 
mortee
Guest
Posts: n/a
 
      10-12-2007
Mr_Tibs wrote:
> Thanks mortee. That sort of worked. Unfortunately, it puts those
> entries that have the 6-th column = nil, at the start of the sorted
> array (instead of at the end). I don't really understand the technique
> used. You are sorting by row, but you are somehow defining and using
> an array with 2 elements (that's what the square brackets do, right?).


Yes. Your code seemed like you want to fall back to the 7th column for
ordering when the 6th column is nil in both rows to compare.

If you do a sort_by, then it'll sort the items (in this case rows) based
on the value the block returns for the item passed to it. And comparing
arrays works this way: if the first elements differ, then their order
determines the final ordering; if they are the same, then the rest of
the arrays get compared, all the way through the last element.

So if you provide the mentioned two-element array as a sort key for your
rows, then the result will be almost what your original code did.
Actually, in the meantime I noticed that when the 6th column is non-nil
and equal in both rows to compare, your code returns equal ordering
independently of the 7th column's values - while my code falls back to
them in this case too.

Reagrding your problem with rows with nil in the 6th column going to the
start: naturally, sort will yield an ascending order, and the default
value substituted in my code is the lowest possible, so they'll get
sorted low (that is, to the start). You're of course free to specify any
default value you like, so that they get sorted to where you want them.

mortee


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Javascript Toolbox - Table Sort utility - Sort on column's @intattribute Rick Javascript 0 06-08-2010 11:44 PM
Numerically sort a file on a given column where column is a $var joemacbusiness@yahoo.com Perl Misc 4 07-18-2008 01:48 PM
Merge Sort in C - array output is same as input after sort routine completes rkk C Programming 9 09-24-2006 08:30 PM
Array sort function sorts on chars not numbers ... help ! how to sort numbers GIMME Javascript 5 07-26-2004 01:28 AM
Ado sort error-Ado Sort -Relate, Compute By, or Sort operations cannot be done on column(s) whose key length is unknown or exceeds 10 KB. Navin ASP General 1 09-09-2003 07:16 AM



Advertisments