2017-09-20 119 views
0

你好,我有一个自定义哈希,需要在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}] 

我怎样才能实现这种格式有效(内存使用情况)? 以下代码修复了引用问题(因为它创建了一个新的散列),但效率很低,因为我的初始散列“数据”非常大。

# 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

@DanilSperansky我认为我们可以使用初始散列并只修改1个键。 –

+1

但是你最终想要一个包含5个不同哈希的数组。他们必须在某种程度上以某种方式创建。 –

回答

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在这种情况下复制的散列,并返回合并它无线的结果th args。

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