100k values in list, need to filter even, odd and prime numbers in three lists

i have a list/array of 100k values. Filter even, odd and prime numbers in separate three lists.
i am new on elixir can anyone help me about it.

Thanks

Have a look at Enum.reduce, Map.update, guard clauses.

something along the lines below should do it, I suppose. You will also need to implement is_prime?. is_odd and is_even are Kernel functions that can be used as guard clauses.

Enum.reduce([1, 2, 3, 4], %{}, fn 
    2, acc -> Map.update(acc, :prime, [x], &([x | &1]))
    x, acc when is_even(x) -> Map.update(acc, :even, [x], &([x | &1]))
    x, acc -> if is_prime?(x), do: Map.update(acc, :prime, [x], &([x | &1])), else: Map.update(acc, :odd, [x], &([x | &1]))
end)

uhh, wait, I made some assumptions I shouldn’t have made. 2 should appear in both even and prime lists? 7 should appear in both odd and prime? Depending on the answer to this, the above example should be adapted a bit.

2 Likes

You know, you also also just use Enum.filter :smiley:

I’m not sure “filter into lists” should be translated to Enum.filter though.

I think it was meant to be split into lists (clauses by @sfusato):

Enum.group_by(list, fn 
  2 -> :prime
  x when is_even(x) -> :even
  x -> if is_prime?(x), do: :prime, else: :odd
end)

… but could as well be have lists filtered by type of data:

%{
  prime: Enum.filter(list, &prime?/1),
  even: Enum.filter(list, &is_even/1),
  odd: Enum.filter(list, &is_odd/1)
}
# or for just one list traversal
Enum.reduce(list, %{prime: [], even: [], odd: []}, fn x, acc -> 
  [prime: prime?(x), even: is_even(x), odd: is_odd(x)]
  |> Enum.filter(fn {_, val} -> val end)
  |> Enum.reduce(acc, fn {key, _} -> 
    Map.update!(acc, key, &([x | &1]))
  end)
end)
3 Likes

Hmm, if you wanted to avoid extra iteration then you could use Enum.group_by to split into multiple lists :even, :odd, :prime, [:odd, :prime], then for every number that is both odd and prime you would add them to both the :odd and :prime lists (technically you would also need [:even, :prime] for just the number 2

1 Like