if i make an object sortable using <=> as so:
def <=> anItem
@date <=> anItem.date
end
and date is nil, it fails. What’s the right way to handle nils in this
scenario?
thanks.
if i make an object sortable using <=> as so:
def <=> anItem
@date <=> anItem.date
end
and date is nil, it fails. What’s the right way to handle nils in this
scenario?
thanks.
def <=> anItem
@date.nil? ? -1 : @date <=> anItem.date
end
You can set the -1, to 0, or 1 depdending where you want the objects
with nil @dates placed.
Farrel
Actually you can shorten it a bit further if you use
@date ? @date <=> anItem.date : -1
That’s due to the fact that in Ruby nil is equivalent to false in
conditional expression.
Farrel
Farrel L. wrote:
Actually you can shorten it a bit further if you use
@date ? @date <=> anItem.date : -1
That’s due to the fact that in Ruby nil is equivalent to false in
conditional expression.
Speaking of this very topic, I am having an issue where I want to sort
objects by two of its attributes in a SortedSet, but its not working
out:
I’d like it to be sorted first by its :a attribute, but if they are
equal, by whatever sorting on the :b attributes comes up with. Anybody
know what I’m doing wrong in this test code? The third and fourth
elements are not in the proper order (excuse the overly verbose <=>
method… I was trying to get it working).
require ‘set’
s = SortedSet.new
s << X.new( 1, 2)
s << X.new( 2, 1)
s << X.new( 3, 3)
s << X.new( 3, 4)
s << X.new( 1, 2)
p s
x = X.new 3, 3
y = X.new 3, 4
p x <=> y
p y <=> x
p x <=> x
puma:~> ./settest
#<SortedSet: {#, #, #, #}>
1
1
1
puma:~>
–
Toby DiPasquale
On 3/9/06, Toby DiPasquale [email protected] wrote:
Speaking of this very topic, I am having an issue where I want to sort
objects by two of its attributes in a SortedSet, but its not working
out:I’d like it to be sorted first by its :a attribute, but if they are
equal, by whatever sorting on the :b attributes comes up with.
as a quick alternative, sorting by several attributes is pretty easy
using #sort_by
X = Struct.new :a, :b
s = []
s << X.new(3, 3)
s << X.new(3, 4)
s << X.new(1, 2)
s << X.new(4, 8)
s << X.new(4, 2)
sorted = s.sort_by { |a| [a.a,a.b] }
sorted.each { |v| p v }
#
#
#
#
#
Cameron
Actually, the weird thing is that the dates were never nil, but the
sort thinks they are. Adding the required nil checking code suppressed
the exception but the sort is returning things in random order because
it sees each date as nil.
I posted a followup on the rails list because I thought it might be a
rails issue. They suggested I use an explicit sort block instead:
@assignments= @assignments.sort {|a,b| a.date <=> b.date}
and it works. Not sure why.
I don’t think you can access the attributes of a Struct from inside it
using object variables (like @a).
C:\Documents and Settings\flifson\Desktop>irb
irb(main):001:0> X = Struct.new :a,:b
=> X
irb(main):002:0> class X
irb(main):003:1> def print_attributes
irb(main):004:2> puts “#{@a}:#{b}”
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> s = X.new ‘hello’,‘world’
=> #<struct X a=“hello”, b=“world”>
irb(main):008:0> s.print_attributes
:world
Notice only the value of the b attribute was printed (‘world’).
That’s because self. was implicitly added to the front of it, so it
became self.b which will return the correct value. Changing it to:
def <=> other
if not a
1
elsif not b
-1
else
if a == other.a
b <=> other.b
else
a <=> other.a
end
end
end
produces:
C:\Documents and Settings\flifson>ruby settest.rb
#<SortedSet: {#, #, #,
#}>
-1
1
0
My guess is that the Struct is really a type of Hash and that it uses
the method_missing system hook to actually retrieve the data from
whatever it uses to store the data. It has a lot of Hash like methods
such as values, each_pair etc etc.
Farrel
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs