Ruby修改并在哈希数组中添加哈希值
我正在尝试使用Ruby修改并在哈希数组中添加哈希值,ruby,Ruby,我正在尝试使用collect修改哈希数组。对于每个哈希,我想添加一个新的键/值,并修改一个不同的键/值。但是,我在使用sub修改现有哈希值时遇到问题。它似乎完全用一个数组项替换了散列,该数组项等于sub!命令 paths = [{:path=>"bin/ruby/file1", :tag=>"v_10"}, {:path=>"usr/name/subdir/file2", :tag=>"v_12"}] paths.collect! do |x| x.merge(Ha
collect修改哈希数组代码>。对于每个哈希,我想添加一个新的键/值,并修改一个不同的键/值。但是,我在使用sub修改现有哈希值时遇到问题代码>。它似乎完全用一个数组项替换了散列,该数组项等于sub!命令
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”}]
您不想收集
,您需要每个。Collect将输入哈希映射到每个块的输出,块的输出是.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"}]
功能型版本
paths.map do |path|
parts = path[:path].split('/');
{
:path => parts.first(parts.length - 1).join('/'),
:tag => path[:tag],
:file => parts.last
}
end
收集代码>不收集
collect
本来可以(使用merge!
而不是merge
)但是有点pointless@muistooshort任何一个选项都是错误的,他只返回了一个值,x[:path].sub!(/\/\w+$/,“”)
来自blockmeagar,感谢您解释我的代码不起作用的原因+答案。我的印象是,我们无法使用每个
就地修改(因此我尝试使用收集
)。在这里创建x[:文件]
是如何工作的?是因为数组项指向散列,而指针实际上没有改变(因此每个
都有效)?您正在迭代对象数组,每次迭代都将x
设置为数组中的下一个对象。在Ruby中,对象是通过值分配的,因此修改x
将修改对象x
指向。如果希望保留数组的原始版本不变,但需要返回全新的对象,或者两个数组都将包含对相同对象的引用,则执行collect
没有错。块的返回值之所以相关,唯一原因是他使用的是collect
,如果他使用了collect
,那么块的返回值就不相关了。你的答案仍然有一个打字错误,因为你的第一句话没有意义。