Ruby 重命名哈希键,但保持顺序(不执行新插入)

Ruby 重命名哈希键,但保持顺序(不执行新插入),ruby,Ruby,我想重命名哈希键。这: myhash[preferred_name] = myhash.delete old_name 在哈希的最后一个索引处插入新的键值对。有没有办法在不添加新哈希的情况下重命名哈希?您可以使用: 只需确保哈希中没有新密钥。您可以使用: 只要确保新密钥没有出现在散列中。我支持@Stefen的答案,但有一个条件,即在2.5之前的Ruby版本首次出现时,不需要支持它。如果必须支持早期版本,这里有一种不创建新哈希的方法,这是OP提到的方法的扩展 h = { foo: 1, bar

我想重命名哈希键。这:

myhash[preferred_name] = myhash.delete old_name 
在哈希的最后一个索引处插入新的键值对。有没有办法在不添加新哈希的情况下重命名哈希?

您可以使用:

只需确保哈希中没有新密钥。

您可以使用:


只要确保新密钥没有出现在散列中。

我支持@Stefen的答案,但有一个条件,即在2.5之前的Ruby版本首次出现时,不需要支持它。如果必须支持早期版本,这里有一种不创建新哈希的方法,这是OP提到的方法的扩展

h = { foo: 1, bar: 2, baz: 3 }

h.keys.each { |k| h[k == :bar ? :qux : k] = h.delete(k) }
  #=> [:foo, :bar, :baz] 
h #=> {:foo=>1, :qux=>2, :baz=>3}
请注意,无法使用枚举数和,因为在迭代过程中会删除键

另一种选择如下

keys = h.keys
keys[keys.index(:bar)] = :qux
h.replace(keys.zip(h.values).to_h)
  #=> {:foo=>1, :qux=>2, :baz=>3}

我支持@Stefen的回答,但有一个附带条件,即在2.5之前的Ruby版本首次发布时,不需要支持它。如果必须支持早期版本,这里有一种不创建新哈希的方法,这是OP提到的方法的扩展

h = { foo: 1, bar: 2, baz: 3 }

h.keys.each { |k| h[k == :bar ? :qux : k] = h.delete(k) }
  #=> [:foo, :bar, :baz] 
h #=> {:foo=>1, :qux=>2, :baz=>3}
请注意,无法使用枚举数和,因为在迭代过程中会删除键

另一种选择如下

keys = h.keys
keys[keys.index(:bar)] = :qux
h.replace(keys.zip(h.values).to_h)
  #=> {:foo=>1, :qux=>2, :baz=>3}
或:

不幸的是,即使在找到匹配项之后,这两种解决方案也会扫描整个结构,因此,如果您的哈希有许多条目,您可能会选择其他选项之一

或:


不幸的是,即使在找到匹配项之后,这两种解决方案也会扫描整个结构,因此,如果您的哈希有许多条目,您可能会选择其他选项之一

当我尝试您现有的解决方案时,它似乎能按预期工作。删除一个键,并为该值指定一个新名称。是的,我不喜欢使用新版本的Ruby,但我会最后插入一个新的索引。我想在哈希表中保持键值对的顺序。我不容易找到一个键值对,可以迭代并将所有选项放入一个新的哈希表中,然后用select修改一个,但这会很快变得混乱。为了以防万一,当我尝试您现有的解决方案时,这里提供了哈希可用的方法—它似乎能按预期工作。删除一个键,并为该值指定一个新名称。你使用的是哪个版本的Ruby?是的,它可以工作,但是它会在最后一个索引中插入一个新的哈希,我不喜欢。我想在哈希表中保持键值对的顺序。我不容易找到一个键值对,可以迭代并将所有选项放入一个新的哈希表中,然后用select修改一个,但这会很快变得混乱。为了以防万一,这里有一些散列可用的方法
h.map { |k, v| [k == old_name ? preferred_name : k, v] }.to_h