20

In Ruby, the array subtraction or reject

>> [1,3,5,7,7] - [7]
=> [1, 3, 5]

>> [1,3,5,7,7].reject{|i| i == 7}
=> [1, 3, 5]

will remove all entries in the array. Is there an easy to remove just 1 occurrence?

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • 1
    This is very close to ["Delete first instance of matching element from array"](http://stackoverflow.com/questions/4595305/delete-first-instance-of-matching-element-from-array). – the Tin Man Jan 19 '11 at 04:30

3 Answers3

29
>> a = [1,3,5,7,7]

>> a.slice!(a.index(7))
=> 7

>> a
=> [1,3,5,7]
mbm
  • 1,902
  • 2
  • 19
  • 28
15

The best I can think of is:

found = false
[1,3,5,7,7].reject{|i| found = true if !found && i == 7}

Or destructively:

arr = [1, 2, 3, 5, 7, 7]
arr.delete_at( arr.index(7))
arr #=> [1, 2, 3, 5, 7]
sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • similarly: arr.slice(arr.index(7)) or arr.slice!(arr.index(7)) – andynu Jan 19 '11 at 04:02
  • 1
    @andynu: The former doesn't do anything. One `slice!` works for this (because it happens to do the same thing as `delete_at` when called with one argument). – sepp2k Jan 19 '11 at 04:09
  • 2
    By the way, in second solution you also may need to add `if pos`, because `delete_at(nil)` throws exeption. – Nakilon Jan 19 '11 at 04:27
-5

While it doesn't directly answer your question, uniq might be what you want.

[1,3,5,7,7].uniq # => [1,3,5,7]
zetetic
  • 47,184
  • 10
  • 111
  • 119
  • This is a bit aggressive. [1,1,1,1,2,2].uniq # => [1,2] removing considerably more than a single seven. – andynu Jan 19 '11 at 04:14
  • it removes all other duplicate elements as well, that's not what OP wants. – ghostdog74 Jan 19 '11 at 04:17
  • Well I did say it didn't answer the question :) That's what I get for trying to guess what the OP is *really* trying to do... – zetetic Jan 19 '11 at 04:25