这是我的哈希:
color_hash = { sky: "blue", curtain: "blue", pavement: "black" }
有没有办法改变它以使两个键映射到相同的结果,如下所示:
color_hash = { sky or curtain: "blue", pavement: "black" }
我希望能够使用color_hash[:sky]
并打印blue
,我可以使用color_hash[:curtain]
并打印blue
。
答案 0 :(得分:1)
不,没有办法在Ruby中使用默认的哈希实现。见Is Ruby pass by reference or by value?。如果这是可能的,那么Hash上的setter方法[]=
必须以允许您通过引用传递的方式实现。
你可以使用一些kludgy语法和Hash的子类实现类似的东西......这样的事情(只是一个警告,这仍然是错误的并且相当未经测试,但是让你知道可能涉及的内容)
class FooHash < Hash
attr_accessor :related
def initialize(*args)
@related = {}
super
end
def []=(*args)
raise ArgumentError.new("ArgumentError: wrong number of arguments (#{args.length} for 2)") unless args.length > 1
value = args.pop
keys = args.dup
args.each_index do |index|
key = keys.delete_at(index)
if related[key]
related[key].each do |related_key|
continue if keys.include?(related_key)
super(related_key, value)
end
else
related[key] = []
end
related[key] += keys
related[key].uniq!
keys.insert(index, key)
end
args.each do |arg|
super(arg, value)
end
end
end
它可以让你做这样的事情:
1.9.3-p550 :036 > hsh = FooHash.new
=> {}
1.9.3-p550 :037 > hsh[:foo, :bar] = :baz
=> :baz
1.9.3-p550 :038 > hsh[:foo]
=> :baz
1.9.3-p550 :039 > hsh[:bar]
=> :baz
1.9.3-p550 :040 > hsh[:foo, :blah] = "baz2"
=> "baz2"
1.9.3-p550 :041 > hsh[:foo]
=> "baz2"
1.9.3-p550 :042 > hsh[:bar]
=> "baz2"
1.9.3-p550 :043 > hsh[:blah]
=> "baz2"
长话短说但是,试图模仿Ruby中的指针操作有点粗暴,不要这样做。
答案 1 :(得分:1)
即使我理解你想要做什么,也要考虑使用不同的数据结构。
color_hash = { sky: "blue", pothole: "black", curtain: "blue",
pavement: "black", roadblock: "red" }
您可以使用Enumerable#group_by:
color_hash.group_by(&:last).tap { |h| h.each_key { |k| h[k].map!(&:first) } }
#=> {"blue"=>[:sky, :curtain], "black"=>[:pothole, :pavement],
# "red"=>[:roadblock]}
color_hash.each_with_object({}) { |(k,v),h|
h.update(v=>[k]) { |_,o,n| o+n } }
#=> {"blue"=>[:sky, :curtain], "black"=>[:pothole, :pavement],
# "red"=>[:roadblock]}
这使用Hash#update
(又名merge!
)的形式,它使用一个块来确定合并的两个哈希中存在的键的值。这里{ |_,o,n| o+n }
就是那个块,其中(局部变量)_
是关键(而不是k
,告诉读者它没有在计算中使用),{ {1}}(“old”)是该键的哈希o
的值,h
是该键合并的哈希值。
答案 2 :(得分:0)
或许试试这个。
$someHashContainer = {:curtain => "Blue", :sky => "Blue"}
def update_variables(value)
$someHashContainer[:curtain] = value
$someHashContainer[:sky] = $someHashContainer[:curtain]
end
puts $someHashContainer
update_variables("Green")
puts $someHashContainer
$someHashContainer[:curtain] = "Red"
puts $someHashContainer
update_variables("Yellow")
puts $someHashContainer
'''
OUTPUT:
{:curtain=>"Blue", :sky=>"Blue"}
{:curtain=>"Green", :sky=>"Green"}
{:curtain=>"Red", :sky=>"Green"}
{:curtain=>"Yellow", :sky=>"Yellow"}
'''