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