facets
facets copied to clipboard
Array#relative_index
One of Sean's extensions is:
class Array
# Get the index of the first matching element relative to another index in an
# array. Starts counting from the anchor index (which has index 0 in the
# array slice used for the Array#index call). Like Array#index, may take a
# block or a value.
#
# %w[ a b c d e f g ].relative_index(4, :f) # => 1
def relative_index(anchor, val=nil, &block)
subarray = self[anchor..-1]
val ? subarray.index(val) : subarray.index(&block)
end
end
I made an issue for this b/c I don't see this particular definition being so useful. It's much clearer just to do the a[anchor..-1].index(foo) one's self. However maybe a more liberal definition could be more useful.
def relative_index(target, relative_to)
i = (Integer === target ? target : index(target))
return nil unless i
j = (Integer === relative_to ? relative_to : index(relative_to))
return nil unless j
j - i
end
This covers much of the same use case but can go further by supporting indexes or objects and can provide a negative index.
One problem though, what if the objects of the array are integers?
I think your criticism is correct. I'd modify your suggestion to solve the integer element problem by allowing the method to take a block:
def relative_index(value, target=nil, &block)
anchor = block ? index(&block) : (target.is_a?(Integer) ? target : index(target))
return nil unless anchor
self[anchor..-1].index(value)
end
This way, if you want to match an integer value, you can use a block to do so.