Bala
Bala

Reputation: 11244

How to pass a range to Enum.filter in Elixir?

Is it possible to pass a range to Elixir's Enum.filter. For e.g.

This works

[1,2,3,4,5] |> Enum.filter(&rem(&1,2)==0) #=> [2,4]

But this doesn't

[1..10] |> Enum.filter(&rem(&1,2)==0) #=> bad argument in arithmetic...

I have a list containing a range that I would like to pass to filter. Eg.

[1..10, 2, 3]

Upvotes: 0

Views: 985

Answers (2)

Dogbert
Dogbert

Reputation: 222168

You don't need to wrap it in [].

iex(1)> 1..10 |> Enum.filter(&rem(&1,2)==0)
[2, 4, 6, 8, 10]

[1..10] is a list of length 1 with the first element equal to the range 1..10.


To filter a list containing numbers and ranges, I would use Enum.flat_map like this:

iex(2)> [1..10, 2, 3] |> Enum.flat_map(fn
...(2)>   n when is_number(n) -> if rem(n, 2) == 0, do: [n], else: []
...(2)>   enum -> Enum.filter(enum, &rem(&1, 2) == 0)
...(2)> end)
[2, 4, 6, 8, 10, 2]

Upvotes: 3

PatNowak
PatNowak

Reputation: 5812

If you want to use parentheses when creating a range for readability, just use ().

(1..10) |> Enum.filter(&rem(&1,2)==0)

In your example the most readable solution is:

# declare anonymous function for checking is number even
is_even = &rem(&1,2) == 0
(1..10) |> Enum.filter(&is_even.(&1))

Upvotes: 2

Related Questions