2014-02-24 128 views
1

我試圖使用collect!修改散列數組。對於每個散列,我想添加1個新的鍵/值並修改不同的鍵/值。但是,我在使用sub!修改現有散列值時遇到問題。它似乎完全取代散列與單個數組條目等於sub的結果!命令Ruby修改並在散列數組中添加散列值

paths = [{:path=>"bin/ruby/file1", :tag=>"v_10"}, {:path=>"usr/name/subdir/file2", :tag=>"v_12"}] 

paths.collect! do |x| 
    x.merge(Hash[:file => x[:path].sub(/.*\//,"")]) # Grab file name 
    x[:path].sub!(/\/\w+$/,"")      # remove file name from path 
end 

結果:
=> ["bin/ruby", "usr/name/subdir"]

期望的結果:
=> [{:path=>"bin/ruby", :tag=>"v_10", :file=>"file1"}, {:path=>"usr/name/subdir", :tag=>"v_12", :file=>"file2"}]

回答

2

你不想collect!,你想each。收集將輸入散列映射到每個塊的輸出,並且塊的輸出是您撥打.sub的結果,這意味着您會得到一個經過轉換的:path值的平面陣列。

你也可以設置按鍵:file直接,而不是建立一個新的哈希,並試圖將其合併:

paths = [{:path=>"bin/ruby/file1", :tag=>"v_10"}, {:path=>"usr/name/subdir/file2", :tag=>"v_12"}] 

paths.each do |x| 
    x[:file] = x[:path].sub(/.*\//, '') 
    x[:path].sub!(/\/\w+$/,"")      # remove file name from path 
end 

puts paths.inspect # [{:path=>"bin/ruby", :tag=>"v_10", :file=>"file1"}, {:path=>"usr/name/subdir", :tag=>"v_12", :file=>"file2"}] 
+0

''收集不'collect'! 'collect'應該沒問題(用merge!而不是merge),但有點沒有意義 –

+0

@ muistooshort這兩個選項都是錯誤的,他返回一個單一值'x [:path] .sub!(/\/\ w + $ /,「」)''塊 – meagar

+0

meagar,謝謝你爲什麼我的代碼不工作+答案的解釋。我的印象是我們無法用'each'在原地進行修改(因此我嘗試使用'collect')。如何在這裏創建'x [:file]'?是否因爲數組入口指向哈希表而該指針實際上並沒有改變(所以'每個'都有效)? –

1

功能語版

paths.map do |path| 
    parts = path[:path].split('/'); 
    { 
    :path => parts.first(parts.length - 1).join('/'), 
    :tag => path[:tag], 
    :file => parts.last 
    } 
end