给出哈希:
{"set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"]}
如何在set_filter条目后添加新的键值对?预期的输出应该是这样的:
{
"set_filter" => ["0"],
"test3" => ["=test3"],
"test1" => ["=test1"],
"test2" => ["=test2"]
}
我想在哈希中的某个位置插入一个新的键值对。
答案 0 :(得分:6)
唯一的哈希提供的顺序是插入顺序,并且只影响迭代。所以你不能真正添加一个特定的元素,除非你愿意删除所有跟随它的插入,然后再插入所有那些元素。
相反,您可能希望使用一对数组,如下所示:
A = [["set_filter", "0"], ...]
然后使用Array#insert
,就像这样
A.insert(2, ["test3", "=test3"])
当订单很重要时,请使用该数组。 当您需要哈希界面时,您可以
A.to_h # yields { 'set_filter' => '0', ... }
答案 1 :(得分:2)
我建议你做以下事情:
def insert_pair(h, key, pair, proximity=:before)
h.to_a.insert(h.keys.index(key) + (proximity==:after ? 1 : 0), pair.first).to_h
end
h = {"set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"]}
pair = {"test3"=>["=test3"]}
insert_pair(h, "set_filter", pair, :after)
#=> {"set_filter"=>["0"], "test3"=>["=test3"], "test1"=>["=test1"], "test2"=>["=test2"]}
insert_pair(h, "set_filter", pair)
#=> {"test3"=>["=test3"], "set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"]}
insert_pair(h, "test2", pair, :after)
#=> {"set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"], "test3"=>["=test3"]}
我已:before
默认为Array#insert。
这是一种替代方法,它不会将哈希值转换为数组,修改数组然后将其转换回哈希值。相反,它将现有哈希分成两个哈希,在它们之间滑动单键哈希,然后将所有三个哈希合并为一个哈希。
def insert_pair(h, key, pair, proximity=:before)
keys = h.keys
before_keys =
case proximity
when :before
key==keys.first ? [[], keys] : keys.slice_before { |k| k == key }
when :after
keys.slice_after { |k| k == key }
end.first
h.select { |k,_| before_keys.include? k }.
update(pair).
update(h.reject { |k,_| before_keys.include? k })
end
insert_pair(h, "set_filter", pair, :after)
#=> {"set_filter"=>["0"], "test3"=>["=test3"], "test1"=>["=test1"], "test2"=>["=test2"]}
insert_pair(h, "set_filter", pair)
#=> {"test3"=>["=test3"], "set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"]}
insert_pair(h, "test2", pair, :after)
#=> {"set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"], "test3"=>["=test3"]}
答案 2 :(得分:1)
对@cary的回答略有改进(我会直接对其进行评论,但我的声誉不足)。
如果您希望一次插入多个哈希键(带有多个键的pair
),则可以使用@cary变体一的以下修改形式:
def insert_pair(h, key, pair, proximity=:before)
h.to_a.insert(h.keys.index(key) + (proximity==:after ? 1 : 0), *pair.to_a).to_h
end
h = {"set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"]}
#insert pair with one hash key
pair = {"test3"=>["=test3"]}
insert_pair(h, "set_filter", pair, :after)
#=> {"set_filter"=>["0"], "test3"=>["=test3"], "test1"=>["=test1"], "test2"=>["=test2"]}
#insert pair with >1 hash keys
pair = {"test3"=>["=test3"], "test4" => ["=test4"], "test5" => ["=test5"]}
insert_pair(h, "set_filter", pair, :after)
#=> {"set_filter"=>["0"], "test3"=>["=test3"], "test4" => ["=test4"], "test5 => ["=test5"], "test1"=>["=test1"], "test2"=>["=test2"]}
注意:pair
可以是一个或多个哈希键,因此这不会破坏原始用例,而只是扩展了它。