From: Bill Kelly Date: 2008-09-18T20:38:18+09:00 Subject: Re: Preserve insert order in a Hash From: "Me Me" > > I think this is not my case, I need a Hash as I explained Here's an implementation for ruby 1.8 ... I apologize for the lack of tests. class InsertOrderPreservingHash include Enumerable def initialize(*args, &block) @h = Hash.new(*args, &block) @ordered_keys = [] end def []=(key, val) @ordered_keys << key unless @h.has_key? key @h[key] = val end def each @ordered_keys.each {|k| yield(k, @h[k])} end alias :each_pair :each def each_value @ordered_keys.each {|k| yield(@h[k])} end def each_key @ordered_keys.each {|k| yield k} end def keys @ordered_keys end def values @ordered_keys.map {|k| @h[k]} end def clear @ordered_keys.clear @h.clear end def delete(k, &block) @ordered_keys.delete k @h.delete(k, &block) end def reject! del = [] each_pair {|k,v| del << k if yield k,v} del.each {|k| delete k} del.empty? ? nil : self end def delete_if(&block) reject!(&block) self end %w(merge!).each do |name| define_method(name) do |*args| raise NotImplementedError, "#{name} not implemented" end end def method_missing(*args) @h.send(*args) end end # example: h = InsertOrderPreservingHash.new h[:aaa] = 0 h[:foo] = 123 h[:bar] = 456 h[:baz] = 789 h.delete :aaa h[:aaa] = 1 h.each_pair {|k,v| p [k,v]} # produces: [:foo, 123] [:bar, 456] [:baz, 789] [:aaa, 1] Regards, Bill