Comprehension filter excludes too much

Hello everybody,

I run into a problem and I don’t know if I’m doing something really wrong or if I don’t understand how the filters of list comprehensions work. I wrote the following code:

for x <- 0..2, y <- 0..2, do: {x,y}

which creates the list:

[{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}]

pretty good so far. But now I want to exclude the tuple {1,1} from it. So I wrote my code like this:

for x <- 0..2, y <- 0..2, (x != 1) && (y != 1), do: {x,y}

but the generated list now excludes every tuple that contains a single 1.
EDIT: the above line is wrong, it obviously doesn’t exclude every tuple with a 1 in it, but tuple {1,2} is missing.
EDIT2: I copy pasted the wrong line, that’s why my list was wrong, actually every 1 is excluded. So Edit1 is wrong.

[{0, 0}, {0, 2}, {2, 0}, {2, 2}]

Am I doing something horribly wrong?

Thanks in advance.

Greetings,
eXodiquas

:wave:

(x != 1) && (y != 1) is short circuting.

So once it sees something with x=1, it evaluates to true.

1 Like

I do not get the question. x != 1 && y != 1 means neither equals 1. Once any of them equals 1, it gets filtered out. The boolean condition should be:

for x <- 0..2, y <- 0..2, !(x == 1 && y == 1), do: {x,y}
#⇒ [{0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 2}, {2, 0}, {2, 1}, {2, 2}]

3 Likes

Sorry guys, I got my boolean logic completly wrong.

It was a long day.

Thanks for the hints. :slight_smile:

2 Likes

Why not just {1, 1} == {x, y}?

3 Likes

Or rather != I’m guessing. ^.^

3 Likes

I never can’t remember if true means to keep or to reject a value…

1 Like

Think of it as Enum.filter, true keeps. :slight_smile:

Which has a very similar problem to me… I often start with Enum.reject/2 and inverted logic. After that works I just rename the function call and remove the !/1

1 Like

Heh, that’s fascinatingly different from most languages. Many languages don’t even have a reject equivalent, just a filter, I’m curious where you picked up that habit, what language? ^.^

GNU make… A co worker of mine was confused why there is a filter-out but no filter-in, and since we were discussing this after office hours with a beer in the hand (and 2 or 3 in mind), I ended up totally confused and since then I have problems to remember the direction of any filter function unless explicitely stated…

1 Like

Hmm? But in gnu make filter is the default filter function (which operates like Enum.filter), filter-out is the oddity inversed function.

If it helps, filtering in python comprehensions works the same as an in elixir/erlang too?

That’s why BuckleScript’s Belt library uses keep instead of filter - i.e. the predicate signals which data to “keep” in the output.

While filter is the established name it doesn’t really clarify the intent behind the predicate - though in common usage it’s a “passing filter”, rather than a “blocking filter”.

2 Likes

That sounds like in a mutating thought though. Filtering in math and signal processing is where the term filter comes from, which means to ‘filter’ the data through to get only the output that goes through the filter. So if you have working in the math/signal worlds then filter makes sense from that too. :slight_smile:

1 Like