Search code examples
listelixirremoving-whitespace

Delete all entries of an element of a list in Elixir (not just the first one)


I found List.delete/2, that deletes only the first entry searched. I was looking for something that deletes all the entries, like

[:a, :b, :c, :a, :a]
|> List.delete_all :a

[:b, :c]

Is there something like that? Perhaps something like List.delete_all/2


Solution

  • You are looking for Enum.reject/2

    Enum.reject(~w|a b c a a|a, & &1 == :a)
    #⇒ [:b, :c]
    

    Sidenote: using pipe for the single operation is considered an anti-pattern by Elixir core team.


    Another (more flexible) possibility would be to use Enum.reduce/3:

    ~w|a b c a a|a
    |> Enum.reduce([],
         &(if &1 == :a, do: &2, else: [&1 | &2]))
    |> :lists.reverse()
    #⇒ [:b, :c]
    

    More erlangish (and elegant) approach would be to use recursion:

    defmodule M do
      def get_rid_of(e, list, acc \\ [])
      def get_rid_of(_, [], acc),
        do: :list.reverse(acc)
      def get_rid_of(e, [e | rest], acc),
        do: get_rid_of(e, rest, acc)
      def get_rid_of(e, [o | rest], acc),
        do: get_rid_of(e, rest, [o | acc])
    end
    M.get_rid_of :a, ~w|a b c a a|a
    #⇒ [:b, :c]