MmmHmm
MmmHmm

Reputation: 3785

How to remove only a single instance of a value from an array in Ruby?

The removal methods for removing a given value from an array all seem to remove every instance of a supplied value. Without knowing its position, how could I only remove a single instance?

foo = 4,4,3,2,6
foo -= [4]
p foo # --> [3, 2, 6]

I get the same result with foo.delete(4)

I can query the array to discern if an instance of the value exists within it and count the number of instances:

foo = 4,4,3,2,6
foo.include?(4) # <-- true
foo.count(4)    # <-- 2

If, for example, an array of dice rolls were made for a game of Yahtzee:

roll_1 = Array.new(5) {rand(1..6)}

and the resulting values were [4, 4, 3, 2, 6] the player might want to select either both fours, or, 2, 3, & 4 for a straight. In the case where the player wants to hold on to a single four for a straight, how can they choose this single instance of the value in a way that the value is verified as being in the array?

Upvotes: 3

Views: 1102

Answers (1)

mwp
mwp

Reputation: 8467

You can use #index (or #find_index) to find the index of the first matching element, and #delete_at (or #slice!) to delete that element:

foo.delete_at(foo.index(4))

Here's another thread that discusses this issue. They recommend adding a guard in case the value being searched for doesn't appear in the array:

foo.delete_at(foo.index(4) || foo.length)

You could use a flag variable and #delete_if until the flag is flipped:

flag = false
foo.delete_if { |i| break if flag; !flag and i == 4 and flag = true }

You could partition the array into matches and non-matches, remove one of the matches, and reconcatenate the array:

matches, foo = foo.partition { |i| i == 4 }
foo.concat(matches[0..-2])

But I think the first option is best. :-)

Upvotes: 3

Related Questions