2013-08-23 29 views
1

我正在檢查下面的哈希hash_volumes是否有一個密鑰,其instance_id與哈希hash_instance的密鑰匹配。將特定值上的兩個哈希合併

hash_volumes = { 
    :"vol-d16d12b8" => { 
     :instance_id => "i-4e4ba679", 
    }, 
} 
hash_instance = { 
    :"i-4e4ba679" => { 
     :arch => "x86_64", 
    }, 
} 

如果是這樣的話,我需要將其合併到hash_instance。我發現,vol-d16d12b8與實例i-4e4ba679比賽,所以我想與hash_instance進行合併,以便最終hash_instance看起來象下面這樣:

hash_instance = { 
    :"i-4e4ba679" => { 
     :arch => "x86_64", 
     :volume => "vol-d16d12b8" # this is new entry to `hash_instance` 
    }, 
} 

我不能如上所述這兩個散列合併。我懷疑我的if聲明是錯誤的。請大家看看下面我的代碼:

hash_volumes.each_key do |x| 
    hash_instance.each_key do |y| 
    if hash_volumes[x][:instance_id] == y ## I think this line is the problem 
     hash_instance[y][:volume] = x 
    end 
    end 
end 

hash_instance 

輸出:

{ 
    :"i-4e4ba679" => { 
     :arch => "x86_64" 
    } 
} 

上面的代碼給hash_instance無添加volume它。我嘗試如下,但沒有工作:

if hash_volumes[x][:instance_id] == "#{y}" 
# => this if statement gives me syntax error 

.....

if hash_volumes[x][:instance_id] =~ /"#{y}"/ 
# => this if statement does not make any changes to above output. 
+0

@sawa,感謝點出來。我編輯了代碼。在編寫測試代碼以便在SO上發佈時,我總是犯錯。 – slayedbylucifer

+0

好。現在我將刪除重複以使您的問題簡潔。 – sawa

+0

@sawa,謝謝.. – slayedbylucifer

回答

3
hash_volumes = { 
    :"vol-d16d12b8" => { 
     :instance_id => "i-4e4ba679", 
    }, 
} 

hash_instance = { 
    :"i-4e4ba679" => { 
     :arch => "x86_64", 
    }, 
} 

hash_volumes.each do |key, val| 
    id = val[:instance_id] #returns nil if the there is no :instance_id key 

    if id 
    id_as_sym = id.to_sym 

    if hash_instance.has_key? id_as_sym 
     hash_instance[id_as_sym][:volume] = id 
    end 
    end 
end 


--output:-- 
{:"i-4e4ba679"=>{:arch=>"x86_64", :volume=>"i-4e4ba679"}} 
+0

。謝謝。 – slayedbylucifer

+0

@slayedbylucifer,find()必須每次都搜索關鍵字。做一次散列查找,例如調用include?()/ has_key?()比通過鍵搜索更高效。另外,我會避免使用,除非不惜一切代價 - 這是一種令人憎惡的行爲。最後,「緊湊」通常意味着「非常難以閱讀」,當然並不意味着更高效,因此不應該效仿。 – 7stud

1

簡單的執行是這樣的:

hash_instance.each do |k1, v1| 
    next unless k = hash_volumes.find{|k2, v2| v2[:instance_id].to_sym == k1} 
    v1[:volume] = k.first 
end 
+1

謝謝。這是簡潔而緊湊的解決方案。 – slayedbylucifer

+0

...和許多不起作用。如果v2沒有這樣的密鑰,那麼v2 [:instance_id]將返回nil,然後nil.to_sym將引發錯誤。如果hash_volumes可以具有如下條目:':googly => {:hello =>「goodbye」},那麼該解決方案需要改變。 – 7stud

+0

@ 7stud我認爲':instance_id'總是作爲一般格式存在。這是我的解釋。 – sawa