Thursday, 10 April 2008

Array.item_after(this)

There are just so many really useful functions in Ruby that every time I look I find something new and funky. So it always surprises me when I look to find something I'd expect to see - that just isn't there.

I was hoping to find an array function that returns "the next item in the list from the given one". I have a set of steps in a workflow all stored in a list. Given the current step, I want to know what the next one is going to be... so that I can send the user on to the next action from the current one.

Luckily Ruby is really easy to extend. ;)

These functions will return the item before/after the given item... or an item of any given offset from the current one. They return nil if the item can't be found in the given list or if the offset would put the index outside the bounds of the array.

class Array
  def item_after(item)
    offset_from(item, 1)
  end
  def item_before(item)
    offset_from(item, -1)
  end
  def offset_from(match, offset = 1)
    return nil unless idx = self.index(match)
    self[idx + offset]
  end
end

Usage:

>> arr = ['a','b','c','d']
=> ["a", "b", "c", "d"]
>> arr.item_after('a')
=> "b"
>> arr.item_before('d')
=> "c"
>> arr.offset_from('a',2)
=> "c"
>> arr.offset_from('d',-3)
=> "a"
>> arr.offset_from('d',10)
=> nil
>> arr.item_after('purple')
=> nil

No comments: