我想在 Array#find_index { |item| 之后找到更多匹配项 block }
第一次匹配。如何查找第二场、第三场等的索引?
换句话说,我想要 Array#find_index
的 pos
参数等效于 Regexp#match(str, pos)
。然后我可以维护一个当前位置索引以继续搜索。
我不能使用 Enumerable#find_all
因为我可能会在调用之间修改数组(在这种情况下,我还会调整我的当前位置索引以反射(reflect)修改)。我不想复制数组的一部分,因为那样会增加 computational complexity我的算法。我想在不复制数组的情况下执行此操作:
new_pos = pos + array[pos..-1].find_index do |elem|
elem.matches_condition?
end
以下是不同的问题。他们只询问数组中的第一个匹配项,再加上一个:
- https://stackoverflow.com/questions/11300886/ruby-how-to-find-the-next-match-in-an-array
- https://stackoverflow.com/questions/4596517/ruby-find-next-in-array
下面的问题更接近,但仍然对我没有帮助,因为我需要在继续下一个之前处理第一个匹配(并且这种方式也与修改冲突):
最佳答案
一个更简单的方法是:
new_pos = pos
while new_pos < array.size and not array[new_pos].matches_condition?
new_pos += 1
end
new_pos = nil if new_pos == array.size
事实上,我认为这可能比我的其他答案要好,因为它更难出错,而且将来不会从周围的代码中引入阴影问题。然而,它仍然很笨拙。
如果条件更复杂,那么你最终需要做这样的事情:
new_pos = pos
# this check is only necessary if pos may be == array.size
if new_pos < array.size
prepare_for_condition
end
while new_pos < array.size and not array[new_pos].matches_condition?
new_pos += 1
if new_pos < array.size
prepare_for_condition
end
end
new_pos = nil if new_pos == array.size
或者,上帝保佑,一个 begin ... end while
循环(尽管这样你会遇到 new_pos
初始值的问题):
new_pos = pos - 1
begin
new_pos += 1
if new_pos < array.size
prepare_for_condition
end
end while new_pos < array.size and not array[new_pos].matches_condition?
new_pos = nil if new_pos == array.size
这看起来很可怕。但是,假设 prepare_for_condition
是不断以小的方式进行调整的东西。这些调整最终会被重构;然而,到那时,重构代码的输出最终也会以不属于旧重构代码的小方式进行调整,但似乎还没有证明自己重构的合理性 - 等等。有时,有人会忘记更改这两个地方。这似乎是病态的;然而,众所周知,在编程中,病态案例经常发生。
关于arrays - Ruby:查找数组中下一个匹配项的索引,或查找偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33998346/