在特定位置插入哈希条目

Ani*_*Ani 4 ruby hash

给出哈希:

{"set_filter"=>["0"], "test1"=>["=test1"], "test2"=>["=test2"]}
Run Code Online (Sandbox Code Playgroud)

如何在set_filter条目后添加新的键值对?预期的输出应该是这样的:

{
  "set_filter" => ["0"],
  "test3" => ["=test3"],
  "test1" => ["=test1"],
  "test2" => ["=test2"]
}
Run Code Online (Sandbox Code Playgroud)

我想在哈希中的某个位置插入一个新的键值对.

Yam*_*vic 6

唯一的哈希提供的顺序是插入顺序,并且只影响迭代.所以你不能真正添加一个特定的元素,除非你愿意删除所有跟随它,插入,然后再插回所有这些元素.

相反,您可能想要使用一对数组,如下所示:

A = [["set_filter", "0"], ...]
Run Code Online (Sandbox Code Playgroud)

然后Array#insert像这样使用

A.insert(2, ["test3", "=test3"])
Run Code Online (Sandbox Code Playgroud)

当订单很重要时,请使用该数组.当您需要哈希界面时,您可以这样做

A.to_h # yields { 'set_filter' => '0', ... }
Run Code Online (Sandbox Code Playgroud)


Car*_*and 4

我建议您执行以下操作:

  • 从哈希中提取键并找到给定键的索引
  • 如果要在给定键之后而不是之前插入给定对,则向索引添加 1
  • 将哈希值转换为数组
  • 在数组中的计算索引之前插入该对(如果索引等于数组的大小,则在最后一个对之后)
  • 将结果数组转换回哈希值

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"]} 
Run Code Online (Sandbox Code Playgroud)

我已将: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"]} 
Run Code Online (Sandbox Code Playgroud)