Ruby Hash密钥参考

时间:2017-09-20 19:19:56

标签: ruby-on-rails ruby hash hashmap hashtable

您好我有一个需要在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}]

如何有效地实现此格式(内存使用)? 以下代码修复了引用问题(因为它创建了一个新的哈希),但效率很低,因为我的初始哈希数据&#39;非常大。

# 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}]

谢谢!

1 个答案:

答案 0 :(得分:1)

你不能。

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复制哈希并返回将其与args合并的结果。

没有办法解决这个问题。 Ruby中的哈希不能从引用中“继承”。