harp:~ > cat a.rb
class CD
ATTRIBUTES = %w(
size
cusip
)
ATTRIBUTES.each{|a| attr_accessor a}
def initialize hash
hash.each{|k,v| send "#{ k }=", v}
end
def inspect
'cd(' << ATTRIBUTES.map{|k| [k,send(k)].join('=')}.join(', ') << ')'
end
end
class CDList < ::Array
def sorted_by *keys
block = lambda{|cd| keys.flatten.map{|k| cd.send k}}
sort_by &block
end
end
class Fixnum
def of
ret = ; times{|i| ret << yield(i) }; ret
end
end
a = CD::new 'size' => rand, 'cusip' => rand
b = CD::new 'size' => a.size, 'cusip' => rand
c = CD::new 'size' => rand, 'cusip' => rand
d = CD::new 'size' => rand, 'cusip' => c.cusip
cdlist = CDList[ a, b, c, d]
[ %w(size), %w(cusip), %w(size cusip), %w(cusip size) ].each do |keys|
puts(('-' * 42), "sorted by <#{ keys.join ',' }>", ('-' * 42))
p cdlist.sorted_by(keys)
puts
end
harp:~ > ruby a.rb
···
On Mon, 24 Oct 2005, New 2 Ruby wrote:
Question: Are there better ways to do this
sort within the container class?
Have class CD with several fields defined,
@list_of_CDs array in class CD_List holding CD pointers,
and a couple of methods to sort array of pointers by any two fields.
Below is relevant class entries and code.
class CD
attr_reader :size, :cusip, :issuer, :matures, ...
....
class CD_List
@@sortkey1= @@sortkey2 = ""
def initialize @list_of_CDs = Array.new end
...
def new_ord(key1='size',key2='matures') #Provide defaults
@@sortkey1, @@sortkey2 = key1, key2 # Set class variables
@list_of_CDs.sort! { |a,b| cmp_item(a,b) } # Sort in place
end
def cmp_item (a,b) # Adapted from Ryan Pavlik
# Allow different sort fields via Class variables
f1 = eval('a.'+@@sortkey1) <=> eval('b.'+@@sortkey1)
f2 = eval('a.'+@@sortkey2) <=> eval('b.'+@@sortkey2)
(f1 == 0 ? f2 : f1)
end
....
listCD = CD_List.new # Initialize it
....
listCD.new_ord('matures','cusip') # Sort list of CDs
__END__
Complete script with test data (143 lines) at:
http://jmauney.freeshell.org/cgi-bin/data/CD_sort2.rb.txt
Comments on entire script also solicited.
Have searched this newsgroup, read FAQ at RubyCentral,
read HTML of Pickax ver. 1, and Googled without success.
Newest Pickax on order.
Using ruby 1.8.2 (2004-12-25) [i386-mswin32]
Email address is _invalid_! Read here; please respond here.
------------------------------------------
sorted by <size>
------------------------------------------
[cd(size=0.0527311303740203, cusip=0.221851657904869), cd(size=0.603176361108372, cusip=0.221851657904869), cd(size=0.745173353626499, cusip=0.899297785462137), cd(size=0.745173353626499, cusip=0.83329161533014)]
------------------------------------------
sorted by <cusip>
------------------------------------------
[cd(size=0.0527311303740203, cusip=0.221851657904869), cd(size=0.603176361108372, cusip=0.221851657904869), cd(size=0.745173353626499, cusip=0.83329161533014), cd(size=0.745173353626499, cusip=0.899297785462137)]
------------------------------------------
sorted by <size,cusip>
------------------------------------------
[cd(size=0.0527311303740203, cusip=0.221851657904869), cd(size=0.603176361108372, cusip=0.221851657904869), cd(size=0.745173353626499, cusip=0.83329161533014), cd(size=0.745173353626499, cusip=0.899297785462137)]
------------------------------------------
sorted by <cusip,size>
------------------------------------------
[cd(size=0.0527311303740203, cusip=0.221851657904869), cd(size=0.603176361108372, cusip=0.221851657904869), cd(size=0.745173353626499, cusip=0.83329161533014), cd(size=0.745173353626499, cusip=0.899297785462137)]
hth.
-a
--
email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
anything that contradicts experience and logic should be abandoned.
-- h.h. the 14th dalai lama
===============================================================================