1

我想重命名哈希键。这:

myhash[preferred_name] = myhash.delete old_name 

在我的哈希的最后一个索引处插入一个新的键值对。有没有办法在不添加新哈希的情况下重命名哈希?

4

3 回答 3

3

您可以使用transform_keys!

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

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

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

于 2018-12-17T16:58:11.213 回答
1

我支持@Stefen 的回答,但前提是不需要支持 2.5 之前的 Ruby 版本,当Hash#transform_keys! 首次亮相。如果必须支持早期版本,这是一种方法(不创建新哈希),是 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}
于 2018-12-17T17:40:39.480 回答
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

不幸的是,这两种解决方案都会扫描整个结构——即使在找到匹配项之后——所以如果你的哈希有很多条目,你可能更喜欢其他选项之一。

于 2018-12-18T04:25:44.820 回答