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. 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 ------------------------------------------ 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 ===============================================================================