我试图理解为什么我从两个表达中得到不同的结果,我认为它们在功能上完全相同。
each
方法:
matches = {}
@entries.each do|entry, definition|
matches.merge!({entry => definition}) if entry.match(/^#{entry_to_find}/)
end
matches
inject
方法:
@entries.inject({}) {|matches, (entry, definition)| matches.merge!
({entry => definition}) if entry.match(/^#{entry_to_find}/)}
each
代码块在运行时给出正确的答案,但inject
一直返回nil
,我不明白为什么。我希望使用inject,因为它是一段更短的代码。
答案 0 :(得分:3)
这是因为如果条件不满足,if
将返回nil
,并且将在下一次迭代中用于matches
的值。请改用Enumerable#each_with_object
:
@entries.each_with_object({}) do |(entry, definition), matches|
matches.merge!({entry => definition}) if entry.match(/^#{entry_to_find}/)
end
答案 1 :(得分:2)
我认为ndn's analysis of why your inject
approach doesn't work是正确的。至于更短的替代方案,因为您希望那些满足您条件的未修改的键值对@entries
,您是否考虑过Hash#select
?
matches = @entries.select { |entry, definition| entry.match(/^#{entry_to_find}/) }