Keeping a hash' sort order?

hi -

sure this is a common question...
i have a hash of stuff that i want to load/keep in a particular order.

irb(main):005:0> hsh = { "one" => 1, "two" => 2, "three" => 3,
"four"=>4, "twentythree"=>23 }

gives back:
=> {"three"=>3, "two"=>2, "twentythree"=>23, "one"=>1, "four"=>4}

ruby sorts the hash in apparent random order (by object id?)

how can i keep the items in the order i want?

someone said i should probly not use a hash at all? however, i do want
to keep the items organized in the order like above, but access thru
hashkeys.

hsh.each_pair{ |tag, val| ...

can i use a more complex structure and sort by some internal key?

thanks!

/dc

···

-------------------------------------------
      David "DC" Collier
      +81 (0)80 6521 9559
      skype: callto://d3ntaku
-------------------------------------------
      Pikkle 株式会社
      http://www.pikkle.com
-------------------------------------------

dc wrote:

hi -

sure this is a common question...

Yes, and that is the exact reason why I suggest you search through the archives before posting.

i have a hash of stuff that i want to load/keep in a particular order.

irb(main):005:0> hsh = { "one" => 1, "two" => 2, "three" => 3,
"four"=>4, "twentythree"=>23 }

gives back:
=> {"three"=>3, "two"=>2, "twentythree"=>23, "one"=>1, "four"=>4}

ruby sorts the hash in apparent random order (by object id?)

how can i keep the items in the order i want?

someone said i should probly not use a hash at all? however, i do want
to keep the items organized in the order like above, but access thru
hashkeys.

hsh.each_pair{ |tag, val| ...

That's not an access by hash key but an iteration. For that nested arrays are sufficient.

can i use a more complex structure and sort by some internal key?

As said, please go to the archives. There are numerous postings and implementations available.

Regards

  robert

hi -

sure this is a common question...
i have a hash of stuff that i want to load/keep in a particular order.

irb(main):005:0> hsh = { "one" => 1, "two" => 2, "three" => 3,
"four"=>4, "twentythree"=>23 }

gives back:
=> {"three"=>3, "two"=>2, "twentythree"=>23, "one"=>1, "four"=>4}

ruby sorts the hash in apparent random order (by object id?)

if you really want to sort on arbitrary keys use an rbtree:

     harp:~ > cat a.rb
     require 'rbtree' # rubyforge or raa

     rb = RBTree.new

     class Key < ::String
       attr 'arbitrary'
       def initialize value, arbitrary
         super value
         @arbitrary = arbitrary
       end
       def <=> other
         self.arbitrary <=> other.arbitrary
       end
     end
     def Key(*a, &b) Key.new(*a, &b) end

     rb[ Key("a", 3) ] = 1
     rb[ Key("b", 2) ] = 2
     rb[ Key("c", 1) ] = 3

     rb.each{|k,v| p [k,v]}

     harp:~ > ruby a.rb
     ["a", 1]
     ["b", 2]
     ["c", 3]

if you want to sort on insertion order use an ordered hash:

     harp:~ > cat a.rb
     require 'alib' # rubyforge or raa
     require 'yaml'

     oh = alib.orderedhash.new

     oh['a'] = 1
     oh['b'] = 2
     oh['c'] = 3

     y oh

     harp:~ > ruby a.rb
     b: 2
     c: 3

more examples and explantions abound on the list if you want to google them.

-a

···

On Sun, 29 Oct 2006, dc wrote:
     a: 1
--
my religion is very simple. my religion is kindness. -- the dalai lama

Facets' Dictionary class can handle arbitray order via #insert(i,k,v),
as well as automatic sort orders (though it is not as fast as rbtree).

T.

···

ara.t.howard@noaa.gov wrote:

On Sun, 29 Oct 2006, dc wrote:

> hi -
>
> sure this is a common question...
> i have a hash of stuff that i want to load/keep in a particular order.
>
> irb(main):005:0> hsh = { "one" => 1, "two" => 2, "three" => 3,
> "four"=>4, "twentythree"=>23 }
>
> gives back:
> => {"three"=>3, "two"=>2, "twentythree"=>23, "one"=>1, "four"=>4}
>
> ruby sorts the hash in apparent random order (by object id?)

if you really want to sort on arbitrary keys use an rbtree:

     harp:~ > cat a.rb
     require 'rbtree' # rubyforge or raa

     rb = RBTree.new

     class Key < ::String
       attr 'arbitrary'
       def initialize value, arbitrary
         super value
         @arbitrary = arbitrary
       end
       def <=> other
         self.arbitrary <=> other.arbitrary
       end
     end
     def Key(*a, &b) Key.new(*a, &b) end

     rb[ Key("a", 3) ] = 1
     rb[ Key("b", 2) ] = 2
     rb[ Key("c", 1) ] = 3

     rb.each{|k,v| p [k,v]}

     harp:~ > ruby a.rb
     ["a", 1]
     ["b", 2]
     ["c", 3]

if you want to sort on insertion order use an ordered hash:

...

if you really want to sort on arbitrary keys use an rbtree:

    harp:~ > cat a.rb
    require 'rbtree' # rubyforge or raa

    rb = RBTree.new

    class Key < ::String
      attr 'arbitrary'
      def initialize value, arbitrary
        super value
        @arbitrary = arbitrary
      end
      def <=> other
        self.arbitrary <=> other.arbitrary
      end
    end
    def Key(*a, &b) Key.new(*a, &b) end

    rb[ Key("a", 3) ] = 1
    rb[ Key("b", 2) ] = 2
    rb[ Key("c", 1) ] = 3

    rb.each{|k,v| p [k,v]}

    harp:~ > ruby a.rb
    ["a", 1]
    ["b", 2]
    ["c", 3]

What's the 'arbitrary' part for? The Key#<=> method is not called. The following has the same output:

     rb = RBTree.new

     rb[ "a" ] = 1
     rb[ "b" ] = 2
     rb[ "c" ] = 3

     rb.each{|k,v| p [k,v]}

···

ara.t.howard@noaa.gov wrote:

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407