是否可以在哈希中间插入一个新项目并重新索引?

时间:2011-02-01 01:33:59

标签: ruby-on-rails ruby hash insert

我把它作为哈希:

>> params[:payments]

{"0"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"1"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"2"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}

是否可以制作新哈希并将其插入特定位置?例如,走这一行:

{"2"=>{":amount_paid"=>"1.00", ":date_paid"=>"1/1/2006"}}

这样哈希就会像现在一样出现:

{"0"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"1"=>{":amount_paid"=>"1.00", ":date_paid"=>"1/1/2006"}}  # <-- Newly inserted line
{"2"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"3"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}

3 个答案:

答案 0 :(得分:4)

尝试使用数组,因为哈希本身并不是有序的。 Ruby的Array.insert允许您指定插入新对象的位置(http://www.ruby-doc.org/core/classes/Array.html#M000230),并使用上面的示例,我们得到:

arr = [{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}]

arr.insert(2, {"some hash"}) 

[{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{"some hash"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}]

然后,您可以迭代索引并在添加时保持所需的顺序。

答案 1 :(得分:3)

在Ruby 1.9+中,Hashes不是订购的,而是维护插入条目的顺序:

来自文档:

  

哈希按照插入相应键的顺序枚举其值。

require 'pp'

hash = {
  'a' => 1,
  'c' => 3
}

hash['b'] = 2

pp hash
# >> {"a"=>1, "c"=>3, "b"=>2}

作为排序哈希键然后遍历哈希的替代方法,哈希本身可以进行排序,如果你想直接遍历它,则重新生成:

ruby-1.9.2-p136 :010 > Hash[*hash.sort.flatten]
 => {"a"=>1, "b"=>2, "c"=>3} 

使用它像:

hash = Hash[*hash.sort.flatten]

使用大哈希对键进行排序然后遍历它们可能会更快,但是如果你必须按顺序进行哈希,那么就可以了。

答案 2 :(得分:1)

如果必须使用Hash执行此操作,并且您不想使用数组的索引,则应创建一个新类OrderedHash。在该课程中,您需要创建一个强制执行以下属性的insertdelete方法:

插入:

  1. 新条目中包含一个键 范围(&lt; =最大当前密钥)。
  2. 如果新条目的密钥是 已经使用过的每个号码来自 当前新的关键值 最大值,增加密钥 价值一个。可能最好做 这从最大的下降到 最小的以避免问题。
  3. 插入新条目
  4. 删除:删除条目时,减少所有键的键值&gt;删除值。