Why does using keep_if in Ruby skip over the first element in an array? -
def unique(arr) return arr.keep_if { |x| arr.count(x) == 1 } end print unique([2, 5, 5, 4, 22, 8, 2, 8]) #=> [4, 22, 2]
the value 2 appears twice in array, using following method incorrectly returns it. why happen, , can fix it?
unfortunately, due hidden behavior in how keep_if
works. illustrate behavior, can make use of lowest-hanging fruit in our debugging orchard, ol' puts
:
def unique(arr) return arr.keep_if { |x| puts x, arr.join(',') arr.count(x) == 1 } end print unique([2, 5, 5, 4, 22, 8, 2, 8])
this gives following output:
2 2,5,5,4,22,8,2,8 5 2,5,5,4,22,8,2,8 5 2,5,5,4,22,8,2,8 4 2,5,5,4,22,8,2,8 22 4,5,5,4,22,8,2,8 8 4,22,5,4,22,8,2,8 2 4,22,5,4,22,8,2,8 8 4,22,2,4,22,8,2,8 [4, 22, 2]
look @ happens whenever method discovers new value wants keep: stores value in 1 of indexes in array, overwriting what's there. next time finds value wants keep, places in next spot, , on.
this means first time keep_if
looks @ 2
, sees 2 of them , decides skip it. sees 4
wants keep, , overwrites first 2
. thus, second time sees 2
, decides keep it.
Comments
Post a Comment