When programming radio buttons on a website, I find myself using this
sort of construct a lot:
@choices = [
['1', 'Spring'],
['2', 'Summer'],
['3', 'Fall']
]
@table = {}
@choices.each do |key, value|
@table[key] = value
end
The data structure I really want is like a hash, except that it
maintains its key/value pairs in the order that I defined them.
Or, looking at it another way, I want an array of arrays, except that
it can be accessed using the key (where the key is the first element
of each array inside the outer array).
Currently, I define it as an array of arrays, and then have a bit of
code to convert it into a hash. Then when I need it in order, I use
the array, and when I need to lookup by key, I use the hash.
Is there a built-in class that Ruby has which would automate this?
When programming radio buttons on a website, I find myself using this
sort of construct a lot:
@choices = [
['1', 'Spring'],
['2', 'Summer'],
['3', 'Fall']
]
@table = {}
@choices.each do |key, value|
@table[key] = value
end
The data structure I really want is like a hash, except that it
maintains its key/value pairs in the order that I defined them.
Or, looking at it another way, I want an array of arrays, except that
it can be accessed using the key (where the key is the first element
of each array inside the outer array).
What about this?
require ‘delegate’
class Hash
class Ordered < DelegateClass(Hash)
def initialize(*array)
super({}) @order =
array.each(&method(:store))
end
def each
@order.each do |key|
yield key, fetch(key)
end
end
def store(key, val)
has_key?(key) or @order << key
super
end
def shift
return if @order.empty?
key = @order.shift
[key, delete(key)]
end
def self.[](*array)
new(*array)
end
end
def self.Ordered(*array)
Ordered.new(*array)
end
end
if FILE == $0
array = [
[‘3’, ‘Fall’],
[‘1’, ‘Spring’],
[‘2’, ‘Summer’],
]
nh = Hash[*array.flatten]
nh.each {|x| p x}
oh = Hash::Ordered[*array]
oh.each {|x| p x}
while x = oh.shift
p x
end
end
···
At Tue, 27 Aug 2002 07:14:19 +0900, Philip Mak wrote:
You can, but it’s ugly. Like Phillip, I have occasionally wanted to
retrieve hash pairs in insertion order. It seems such a simple request.
It’s not something I expect of the language, but a module would be nice.
Perl has IxHash for this. I know absolutely nothing else about it, but
maybe I’ll implement it! (Maybe it already exists on RAA, but I haven’t
seen it.)
By the way, to convert array = [[a,1], [c,2], …] to a hash, you can use:
(hang on, I thought there was a built-in way to do it in one expression -
I must be wrong)