From: ahoward Date: 2003-08-28T07:52:52+09:00 Subject: Re: sorting on hash contents On Wed, 27 Aug 2003, Mark Probert wrote: > Hi, all. > > Say I have a hash of 4 elements, val[1..3] and name > > h["a"] = "1,2,3,fred" > h["b"] = "4,1,2,jack" > h["c"] = "3,3,4,jill" > > How do I define: > > def sort_hash(field="val1") > h.each { |key, data| > (val1, val2, val3, name) = data.split(/,/) > # etc.. > end > > elegantly? > > One possibility is to write it out to a tempfile and use > the external `sort` command. Is there an easy pure-ruby > solution? > > TIA, whenever i end up needing sorted hashes i ALWAYS use the rbtree package from the raa - it is awesome. eg: ----CUT---- #!/usr/bin/env ruby require 'rbtree' # get this from the raa - it's FAST and always sorted class DB < RBTree attr :pks alias pk pks attr :fields attr :n_pks attr :n_fields attr :indices def initialize args @pks = (args[:pks] or args[:pk]).to_a @fields = args[:fields].to_a pks.map{|k| raise unless fields.include? k} @n_pks = pks.size @n_fields = fields.size @indices = {} fields.map{|f| indices[f] = RBTree.new} end def []= k, v k, v = [k, v].map{|a| a.to_a} raise unless k.size == pk.size and v.size == fields.size # map each field back to this k->v pair... @fields.each_with_index{|f,i| indices[f][v[i]] = [k,v]} super k, v end def sorted_by field raise unless block_given? indices[field].map{|k,v| yield k, v} end end db = DB.new :pk => 'f0', :fields => ['f0', 'f1', 'f2'] db['a'] = '0', 'C', 'b' db['b'] = '1', 'B', 'a' db['c'] = '2', 'A', 'c' puts '--' db.sorted_by('f0') do |k,v| p v end puts '--' db.sorted_by('f1') do |k,v| p v end puts '--' db.sorted_by('f2') do |k,v| p v end __END__ OUTPUT: -- [["a"], ["0", "C", "b"]] [["b"], ["1", "B", "a"]] [["c"], ["2", "A", "c"]] -- [["c"], ["2", "A", "c"]] [["b"], ["1", "B", "a"]] [["a"], ["0", "C", "b"]] -- [["b"], ["1", "B", "a"]] [["a"], ["0", "C", "b"]] [["c"], ["2", "A", "c"]] ----CUT---- -a ==================================== | Ara Howard | NOAA Forecast Systems Laboratory | Information and Technology Services | Data Systems Group | R/FST 325 Broadway | Boulder, CO 80305-3328 | Email: ara.t.howard@noaa.gov | Phone: 303-497-7238 | Fax: 303-497-7259 | ~ > ruby -e 'p(%.\x2d\x29..intern)' ====================================