Drop_by and confusion

Hello Elixir comunity!

New user here. I’ve been learning elixir for a while now but haven’t registered before. Now I encountered a very strange behaviour with enums. Or this could be all in my mind. Anyway, here goes…

Am I completely missing the intended function of ‘drop_dy’? Shouldn’t it drop the elements returning false when passed a function.

Example:

iex(25)> Enum.drop_while(1..10, fn(x) -> x < 5  end)
[5, 6, 7, 8, 9, 10]

Just what I expected. Range is dropped when it’s smaller than 5. Ok, going on…

iex(26)> Enum.drop_while(1..10, fn(x) -> is_integer(x) end)
[]

Yes, still understanding. Those are integers and return true so they are dropped. Going on…

iex(27)> Enum.drop_while(1..10, fn(x) -> rem(x, 2) != 0  end)
[2, 3, 4, 5, 6, 7, 8, 9, 10]

Now I’m lost. Why did it only drop the number one? Shouldn’t all the uneven numbers be dropped since the remainder is one? I even checked that rem really returns the remainder

iex(28)> rem(9, 2)
1

It does. I’m still confused. What about this one

iex(29)> Enum.drop_while(1..10, fn(x) -> x != 5  end)
[5, 6, 7, 8, 9, 10]
iex(30)>

Again. Where did this come from? Shouldn’t everything else but 5 be dropped?

This might be that I’ve got some fundamentally wrong understanding going on here. So please help me :slight_smile:

It stops dropping as soon it encounters first falsey value

[true, false, true, false, true, false, true, false, true, false]
so drops 1 then function returns false and it stops dropping.
You can use Enum.filter to do what you were trying to do with drop_while

That explains it. Thanks, I thought I was completely going bonkers.

1 Like