我必须在数组中搜索一个项目并返回下一个项目的值。例子:
a = ['abc.df','-f','test.h']
i = a.find_index{|x| x=~/-f/}
puts a[i+1]
除了使用索引之外,还有什么更好的方法吗?
我必须在数组中搜索一个项目并返回下一个项目的值。例子:
a = ['abc.df','-f','test.h']
i = a.find_index{|x| x=~/-f/}
puts a[i+1]
除了使用索引之外,还有什么更好的方法吗?
经典的函数方法不使用索引(xs.each_cons(2)
-> xs 的成对组合):
xs = ['abc.df', '-f', 'test.h']
(xs.each_cons(2).detect { |x, y| x =~ /-f/ } || []).last
#=> "test.h"
使用Enumerable#map_detect可以稍微简化一点:
xs.each_cons(2).map_detect { |x, y| y if x =~ /-f/ }
#=> "test.h"
类似的东西array.find{something}.next
不存在的原因是它是一个数组而不是链表。每一件物品都是它自己的价值;它没有“我之后的项目”的概念。
@tokland 通过使用每对连续项目迭代数组提供了一个很好的解决方案,这样当第一个项目匹配时,您就可以方便地使用第二个项目。可以肯定的是,对于函数式风格有很强的论据。不过,您的版本更短,而且我认为您的版本也更快速、更容易理解。
如果问题是您经常使用它并且想要一些更清洁和更重要的东西,那么您当然可以将它作为单例方法添加到a
:
def a.find_after(&test)
self[find_index(&test).next]
end
然后
a.find_after{|x| x=~/-f/}
是在第一次匹配后找到下一个项目的清晰方法。
综上所述,我认为@BenjaminCox 对您的实际目标提出了最佳观点。如果您正在解析命令行选项,那么有些库可以做得很好。
我不知道执行该特定操作的更清洁方法。但是,看起来您确实在尝试解析命令行参数。如果是这样,我建议使用内置的 OptionParser 模块 - 它会节省大量时间和头发拉扯试图自己解析它们。
这篇文章解释了它是如何工作的。
正如其他人所评论的那样,您使用索引的解决方案很好。您可以使用Enumerable#drop_while
从匹配中获取数组并获取其中的第二个元素:
a = ['abc.df','-f','test.h']
f_arg = a.drop_while { |e| e !~ /-f/ }[1]