On 2/4/06, Dave Howell <groups / grandfenwick.net> wrote:
> I thought I was actually going to enter my first RubyQuiz, but I've
> spent three times as much time trying to get Ruby to stop surprising me
> as I have trying to implement my algorithm, and I've had to abandon my
> effort since I don't have the time to spend. Sigh.
>
> Can somebody explain to me how I'm supposed to delete a *single*
> element from an array based on equivalence with an object? and get back
> said array with said element deleted?
>
> In other words....
>
> ar = [1, 2, 3, 8, 15, 15, 8]
>
> ar.delete_one_element!(15)
> => [1, 2, 3, 8, 15, 8]
>
> ar.delete_one_element!(14)
> => [1, 2, 3, 8, 15, 15, 8]
>
> ar.delete_one_element!(nil)
> => [1, 2, 3, 8, 15, 15, 8]
>
> I did find so many different ways of not doing this....
>
> Too enthusiastic....
> ar.delete(15)
> => 15
> ar
> => [1, 2, 3, 8, 8]
>
> Right results, wrong output...
> ar.slice!(ar.index(15))
> => 15
> ar
> => [1, 2, 3, 8, 15, 8]
>
> and also surprised me by not handling 'nil' as I wanted...
> ar.slice!(ar.index(13))
> TypeError: no implicit conversion from nil to integer
>          from (irb):8:in `slice!'
>          from (irb):8
>
>
> I mean, this seems so, er, obvious! "Please find one instance of this
> object in the array, and return to me the array without that object. If
> the array doesn't have that object, then just give the array back to
> me."
>
> Why isn't that the Ruby Way? What am I missing here?
>
> Help?

If I'm understanding you properly, this is one way:

class Array
  def delete_one_element!(value)
    return self unless i = self.index(value)
    self[i] = nil
    self.compact!
  end
end

irb(main):023:0> ar = [1,2,3,8,15,15,8]
=> [1, 2, 3, 8, 15, 15, 8]
irb(main):024:0> ar.delete_one_element!(15)
=> [1, 2, 3, 8, 15, 8]
irb(main):025:0> ar.delete_one_element!(99)
=> [1, 2, 3, 8, 15, 8]
irb(main):026:0>

Someone will probably post a solution that uses inject, though. Heh.