2014-02-24 129 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