Удалить не только первый элемент списка в Elixir - PullRequest
0 голосов
/ 25 августа 2018

Можно ли удалить все записи для элемента списка в Elixir?Я нашел List.delete/2, который удаляет только первую найденную запись.Я искал что-то, что удаляет все записи, например

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

[:b, :c]

Есть что-то подобное?Возможно что-то вроде List.delete_all/2

Ответы [ 3 ]

0 голосов
/ 25 августа 2018

Вы ищете Enum.reject/2

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

Sidenote: использование трубы для одной операции Elixir считается антишаблономосновная команда.


Другая (более гибкая) возможность - использовать Enum.reduce/3:

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

Более эрлангский (и элегантный)подход будет использовать рекурсию:

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]
0 голосов
/ 29 августа 2018

Вы также можете использовать понимание с фильтром:

iex(1)> for x <- [:a, :b, :c, :a, :a], x !== :a, do: x
[:b, :c]

Или использовать защиту вместо фильтра:

iex(2)> for x when x !== :a <- [:a, :b, :c, :a, :a], do: x
[:b, :c]
0 голосов
/ 25 августа 2018
[:a, :b, :c, :a, :a] |> Enum.reject( fn x -> x == :a end )

т

[:b, :c]
...