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

时间:2018-12-17 16:41:26

标签: ruby

我想重命名一个哈希键。这个:

myhash[preferred_name] = myhash.delete old_name 

在哈希的最后一个索引处插入一个新的键值对。是否可以在不添加新哈希的情况下重命名哈希?

3 个答案:

答案 0 :(得分:3)

您可以使用transform_keys!

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

h.transform_keys! { |k| k == :bar ? :qux : k }
#=> {:foo=>1, :qux=>2, :baz=>3}

只需确保哈希中不存在新密钥即可。

答案 1 :(得分:1)

我第二次回答@Stefen,条件是Hash#transform_keys!首次亮相时就不必支持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}

请注意,枚举数Hash#each_keyHash#each不能使用,因为在迭代过程中将删除键。

以下是另一种选择。

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

答案 2 :(得分:0)

myhash.to_a.each { |a| a[0] = preferred_name if a[0] == old_name }.to_h

或者:

h.map { |k, v| [k == old_name ? preferred_name : k, v] }.to_h

不幸的是,即使找到匹配项,这两种解决方案仍会扫描整个结构,因此,如果您的哈希中有很多条目,则您可能会更喜欢其他选项之一。