0

In the code below I get the expected result:

(the point of the learning exercise I'm working on is to write code to modify the original array rather than returning a new array)

def filter_out!(array, &prc)
    array.uniq.each { |el| array.delete(el) if prc.call(el) } #my block of code
end

arr_2 = [11, 17, 13, 15 ]
filter_out!(arr_2) { |x| x.odd? }
p arr_2     # []

However, if I remove the .uniq and only utilize array.each the output changes to [17, 15].

I believe the difference is that when only using array.each the index is being cycled through and when deleting 11 (because its odd) at the zero index, it looks at the next index, 1, but 17 is no longer at that index (13 is now) so the element is skipped for testing against the block. Same for 15 which is why it and 17 remain.

Is my assumption correct? If so, how does the underlying functionality of .uniq bypass this? I would assume that chaining .uniq in before .each would simply return the same 'incorrect answer' of [17, 15] since all values are already unique and .each would once again be performed on [11, 17, 13, 15 ] .

1 Answer 1

2

Is my assumption correct?

Yes.

How does the underlying functionality of .uniq bypass this?

Because calling this method returns a NEW OBJECT, so you're no longer mutating the object that's being iterated over.

# Your object_ids will be different!
arr_2.object_id
  #=> 70302248117520

arr_2.uniq.object_id
  #=> 70302210605760
Sign up to request clarification or add additional context in comments.

3 Comments

Similarly instead of calling .uniq, you could call .dup to get a "new object". Although of course there are simpler ways of writing this code overall, such as using delete_if.
Ah, got it. So index[1] of one on the new object is still 17 because I deleted index[0] on the original object. Thanks!
Used delete_if as well. As a new programmer they're always teaching the long ways to do things so you understand the fundamentals (like my question) before the shortcuts. Always good to get more methods into my tool belt. I'm sure there are a dozen ways to skin this cat. Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.