Search code examples
rubyselectsequencedigits

How does one remove only 3 instances of the same digits in an Array when there are more than 3 in the Array?


Let's say I have an Array that contains more than three repetitions of a given digit. I want to remove only three of those repetitions, and leave any remaining instances of the digit in the resulting array.

For example:

a = [2, 2, 2, 1, 6]
b = a.map{|i|
    num = a.select{|v| v == i}.size
    num == 3 ? "" : i
    }.reject{|v|
        v == ""
    }

gives me my desired result:

b == [1, 6]

However, in the below example, I want the last "2" to remain in the array.

# I want to reject ONLY triplets.
# In the below example, the last "2" should remain
a = [2, 2, 2, 1, 2]
b = a.map{|i|
    num = a.select{|v| v == i}.size
    num == 3 ? "" : i
    }.reject{|v|
        v == ""
    }

The result here is:

b == [2, 2, 2, 1, 2]

I'd like the result to be:

b == [1, 2]

I also have another code block, similar to the one above, using a bit different logic, but ends up with the same result:

a = [2, 2, 2, 1, 2]
newdice = a.reject { |v|
    if a.count(v) == 3
        x = v
    end
    v == x
    }

I'm at a loss, other than some nasty trickery that involves finding the index of the first instance of the 3x repeated digit, and slicing out [index, 2] from it. There's got to be a more "ruby-like" way.

Thanks!


Solution

  • This would remove the first 3 elements that are = 2

    3.times{a.index(2)? a.delete_at(a.index(2)) : nil }
    

    if you want to remove the first 3 of any digits in the array then something like:

    (0..9).each{|n| 3.times{a.index(n)? a.delete_at(a.index(n)) : nil }}
    

    Matt's version further modified using the if-modifier:

    (0..9).each{|n| {3.times{a.delete_at(a.index(n))} if a.count(n) >= 3}