Ruby 哈希键参考

Ruby Hash Key Reference

您好,我有一个自定义哈希需要在 API 中返回。但目前我正在努力寻找这样做的好方法。下面的例子将描述这个问题。

假设我们有以下代码:

data = {name: "Jon", value: "13"}
results = []

[1, 2, 3, 4, 5].each do |i|
  data[:id] = i
  results << data
end

# output 
# results = [{name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}, {name: "Jon", value: "13", id: 5}]

我期待这样的事情:

# results = [{name: "Jon", value: "13", id: 1}, {name: "Jon", value: "13", id: 2}, {name: "Jon", value: "13", id: 3}, {name: "Jon", value: "13", id: 4}, {name: "Jon", value: "13", id: 5}]

如何有效地实现这种格式(内存使用)? 下面的代码修复了引用问题(因为它创建了一个新的散列)但是效率低下,因为我的初始散列 'data' 真的很大。

# inefficient but working
[1, 2, 3, 4, 5].each do |i|
  data[:id] = i
  results << data.dup
end

# output
# results = [{name: "Jon", value: "13", id: 1}, {name: "Jon", value: "13", id: 2}, {name: "Jon", value: "13", id: 3}, {name: "Jon", value: "13", id: 4}, {name: "Jon", value: "13", id: 5}]

谢谢!

你不能。

Ruby(以及几乎所有其他编程语言)中的引用指向内存中的单个对象。

irb(main):004:0> h = { foo: :bar }
=> {:foo=>:bar}
irb(main):005:0> h.object_id
=> 70125571572420

只要我改变 h 我仍然在使用相同的参考:

irb(main):006:0> h[:bar] = 'baz'
=> "baz"
irb(main):007:0> h.object_id
=> 70125571572420

如果我想要一个稍微不同的 h 版本而不改变 h 它当然会作为一个单独的对象存储:

h.merge(x: 2).object_id
=> 70125567041320

.merge 在这种情况下复制散列和 returns 将它与 args 合并的结果。

没有办法解决这个问题。 Ruby 中的哈希不能 "inherit" 来自引用。