Array comparison returning nil


#1

I am comparing two arrays with:

original_item_ids.sort <=> new_item_ids.sort

However, this returns nil, which seems to be against the documentation
which says the result will be -1, 0 or 1. Both arrays contain the same
values, alhough in a different order, hence the sort.

Does anyone know of any circumstance that would cause this?

Thanks,

Julian


#2

“J” == Julian G. removed_email_address@domain.invalid writes:

J> Does anyone know of any circumstance that would cause this?

moulon% ruby -e ‘p [“a” , 2] <=> [3, 4]’
nil
moulon%

Guy Decoux


#3

Julian G. wrote:

I am comparing two arrays with:

original_item_ids.sort <=> new_item_ids.sort

However, this returns nil, which seems to be against the documentation
which says the result will be -1, 0 or 1. Both arrays contain the same
values, alhough in a different order, hence the sort.

Does anyone know of any circumstance that would cause this?

Improper implemented <=> method on one of the array members:

o=Object.new
=> #Object:0x4a7c118

def o.<=>(x) nil end
=> nil

[o] <=> [1]
=> nil

Kind regards

robert

#4

But http://www.rubycentral.com/ref/ref_c_array.html#_lt_eq_gt

“Returns an integer -1, 0, or +1 …”

I sometimes get 0 and sometimes nil.

Julian


#5

It seems <=> is not much use if it can’t be relied on to do what it
says.

I now need to compare my arrays with:

original_item_ids.sort.join(’-’) == new_item_ids.sort.join(’-’)

Which is messy.

Julian


#6

Hi –

On Fri, 3 Mar 2006, Julian G. wrote:

It seems <=> is not much use if it can’t be relied on to do what it
says.

I now need to compare my arrays with:

original_item_ids.sort.join(’-’) == new_item_ids.sort.join(’-’)

Which is messy.

Can you show an example of two arrays with the same elements that give
you nil when sorted and compared with <=> ?

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#7

On Mar 3, 2006, at 5:37 AM, Julian G. wrote:

I am comparing two arrays with:

original_item_ids.sort <=> new_item_ids.sort

However, this returns nil, which seems to be against the documentation
which says the result will be -1, 0 or 1. Both arrays contain the same
values, alhough in a different order, hence the sort.

Does anyone know of any circumstance that would cause this?

It works for me…

% irb
irb(main):001:0> a = [1,2,3]
=> [1, 2, 3]
irb(main):002:0> b = [3,1,2]
=> [3, 1, 2]
irb(main):003:0> a.sort <=> b.sort
=> 0

Maybe you could post an irb session of your own so we could see
what’s happening?

–Steve


#8

Stephen W. wrote:

Maybe you could post an irb session of your own so we could see
what’s happening?

Not really possible. I am writing a Rails application with a sortable
list on a web page. An XML_Http_request serialises the ids of the list
items and POSTs them to my action controller. By the time I see this
data it is an array of identifiers (numbers) in params[:itemlist].

I extract this to a local array with:

new_item_ids = []
params[:itemlist].each {|item| new_item_ids << item}

I want to compare this with another local array of my original
(unsorted) identifiers. i.e.

original_item_ids.sort <=> new_item_ids.sort

This doesn’t work, although this does:

original_item_ids.sort.join('-') == new_item_ids.sort.join('-')

It is odd that join works to produce the expected string where <=>
thinks it has a problem.

Julian


#9

On Mar 3, 2006, at 8:37 AM, Julian G. wrote:

Thanks,

Julian


Posted via http://www.ruby-forum.com/.

<=> will return nil when a comparision makes no sense

eg:

irb(main):013:0> a = “a”
=> “a”
irb(main):014:0> b = 2
=> 2
irb(main):015:0> a <=> b
=> nil


#10

Hi –

On Sat, 4 Mar 2006, Logan C. wrote:

data it is an array of identifiers (numbers) in params[:itemlist].

Based on join working this is my theory. One of the two arrays have nil’s in
it. nil.to_s is “” but nil <=> anything save nil is nil and will cause the
comparision to fail.

However:

[1,2,nil,3].join("-")
=> “1-2–3”

so you’d get those extra -'s in one but not in the other if one but
not the other had nils.

I wonder whether the params[:itemlist] is producing strings while the
original array is integers. That would explain join working but <=>
giving up:

irb(main):009:0> [“1”,“2”] <=> [1,2]
=> nil
irb(main):010:0> [“1”,“2”].join("-") == [1,2].join("-")
=> true

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#11

On Mar 3, 2006, at 1:12 PM, Julian G. wrote:

original_item_ids.sort.join('-') == new_item_ids.sort.join('-')

It is odd that join works to produce the expected string where <=>
thinks it has a problem.

Julian


Posted via http://www.ruby-forum.com/.

Based on join working this is my theory. One of the two arrays have
nil’s in it. nil.to_s is “” but nil <=> anything save nil is nil and
will cause the comparision to fail.


#12

On Mar 3, 2006, at 3:33 PM, removed_email_address@domain.invalid wrote:

However:

[1,2,nil,3].join("-")
=> “1-2–3”

so you’d get those extra -'s in one but not in the other if one but
not the other had nils.

I doubt he’s displaying the result of the join when doing the
comparison, it would still compare whether or not there are double
dashes


#13

Hi –

On Sat, 4 Mar 2006, Logan C. wrote:

I doubt he’s displaying the result of the join when doing the comparison, it
would still compare whether or not there are double dashes

It’s not a display thing; it’s a <=> or == thing. If the two arrays
have unequal numbers of nils, and you join them with “-”, the results
will not be equal. Actually, I realize now that since he’s sorting
them, he’ll never get that far anyway, because this:

[1,2,3,nil].sort

won’t work at all; nor will [“1”, “2”, “3”, nil].sort.

I’ll keep my money on the theory that one array contains integers and
one contains string representations of the same integers :slight_smile:

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#14

On Mar 3, 2006, at 4:21 PM, removed_email_address@domain.invalid wrote:

so you’d get those extra -'s in one but not in the other if one but

[1,2,3,nil].sort

won’t work at all; nor will [“1”, “2”, “3”, nil].sort.

I’ll keep my money on the theory that one array contains integers and
one contains string representations of the same integers :slight_smile:

David

Good point.


#15

Julian G. wrote:

new_item_ids = []
params[:itemlist].each {|item| new_item_ids << item}

new_item_ids = params[:itemlist]

thinks it has a problem.
See if this raises an error:
(original_item_ids + new_item_ids).sort


#16

Thanks very much to Logan, David and William. David hit on the answer by
pointing out that one array has integers and the other has strings. When
I load my original id array with the values .to_s, the comparison works
as expected. Hooray! I should have realised that anything returned from
a web page would be a string.

Anyway, thanks very much, guys, for taking the time to follow this
through. I really appreciate it.

Julian