2015-06-23 35 views
2

如果你把一個哈希:查找和多維散列內更換 - 紅寶石

{ 
    :element => { 
     :to_find => 'found me' 
    }, 
    :element_2 => { 
     :inner_element => { 
     :n_elements => { 
      :to_find => 'found me' 
     } 
     :do_not_touch => 'still here' 
     } 
    } 
} 

我怎麼能找到並替換:to_find與「改變」?

我試圖

(hash).update(hash){|k,v| (([:to_find].include? k) ? 'changed' : v} 

然而,這僅僅是一個很深。

我可以做一個遞歸函數,例如具有如:

def change_keys(hash, keys, new_value) 
    (hash).update(hash) do |k,v| 
     if (keys.include? k) 
     new_value 
     else 
      if v.class == Hash 
      find_key(v) 
      else 
      v 
      end 
     end 
    end 
end 

我已經測試,運行此,工作原理:

change_keys(my_hash, [:to_find], 'changed') 

然而,有一個更清潔的方式?

回答

1

遞歸方法是要走的路,但你可以把它清潔...

def change_keys(hash, keys, new_value) 
    keys.each { |k| hash[k] = new_value if hash.has_key?(k) } 
    hash.values each { |v| change_keys(v, keys, new_value) if v.class == Hash } 
end 
0

我想你可以嘗試這樣的事情

eval({ 
    :x => 'y', 
    :q => 
    { 
    :x => 'y', 
    :s => 
     { 
     :x => 'y' 
     } 
    } 
}.to_s.gsub(/:x=>"."/, ':x=> "new_value"') 
) 
+1

有趣的方法,但如果你看看在他的「我嘗試過......」中,你會看到他想改變價值,而不是關鍵。 – SteveTurczyn

+0

@SteveTurczyn謝謝你的評論,我更正了我的答案 – Pavel