我必须搜索数组中的项并返回下一项的值。例如:
a = ['abc.df','-f','test.h']
i = a.find_index{|x| x=~/-f/}
puts a[i+1]
除了使用索引之外还有更好的方法吗?
答案 0 :(得分:3)
经典函数方法不使用索引(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"
答案 1 :(得分:3)
array.find{something}.next
之类的不存在的原因是它是一个数组而不是一个链表。每个项目都是它自己的价值;它没有“跟在我后面的物品”的概念。
@tokland通过使用每对连续项目迭代数组来提供一个很好的解决方案,这样当第一个项目匹配时,您可以方便地使用第二个项目。可以肯定的是,功能风格有很强的争论。不过,你的版本较短,而且我认为你的版本也会更快,更容易理解。
如果问题是你经常使用它并想要更清洁,更重要的话,那么你当然可以将它作为单例方法添加到a
:
def a.find_after(&test)
self[find_index(&test).next]
end
然后
a.find_after{|x| x=~/-f/}
是在第一场比赛后找到下一个项目的明确方法。
所有这一切都说,我认为@BenjaminCox最能说明你的实际目标。如果您正在解析命令行选项,那么有很好的库可以做到这一点。
答案 2 :(得分:1)
我不知道如何更清洁地进行特定操作。但是,它确实看起来像是在尝试解析命令行参数。如果是这样,我建议使用内置的OptionParser模块 - 它会节省大量的时间和拉毛试图自己解析它们。
This article解释了它是如何运作的。
答案 3 :(得分:0)
使用索引的解决方案很好,正如其他人所评论的那样。您可以使用Enumerable#drop_while
从匹配中获取数组并获取其中的第二个元素:
a = ['abc.df','-f','test.h']
f_arg = a.drop_while { |e| e !~ /-f/ }[1]