Deleting item from a list

Hello, can anybody help here…? I have a list of players and I what to delete an element, but every for loop the list is reverting to original list. See code below

list = Enum.filter(players, fn(x) ->  # Sys.Log.debug("#{x["category"]}")
                x["category"] == category
            end)

              for _ <- 1..num do
                playerMapElement = Enum.random(list)

                List.delete(list, playerMapElement)

                player
            end
1 Like

The function returns the updated list. It doesn’t modify the list in place.

1 Like

Couple of things here. The most important is that data is immutable.

Secondly however while this may seem like a nitpick, the formatting here makes it super hard to figure out what’s going on. A more idiomatic presentation of this code might be:

list = Enum.filter(players, fn(x) ->
  x["category"] == category
end)

for _ <- 1..num do
  player_map_element = Enum.random(list)

  List.delete(list, player_map_element)

  player
end

Note that I also made the player_map_element variable snake case instead of camel case.

It’s a bit hard to help you figure out what to do because there’s so much context missing. What is the player variable? Where does it come from? Why are you returning it from the loop that’s deleting stuff?

1 Like
def remove_random_players_from_category(players, category, n) do
  players 
  |> Enum.filter(fn(player) ->
          player["category"] == category
      end) 
  |> remove_random_players(n)
end

def remove_random_players(players, 0), do: players
def remove_random_players(players, n) do
    random = players
    |> Enum.random
    players 
    |> List.delete(random)
    |> remove_random_players(n-1)
end

I haven’t actually tested this but suspect it’s what you are trying to do - it looks like you are trying to treat elixir like an imperative language (like Ruby).

I am also not sure this kind of “for loop” sugar on top of erlangs list comprehension is really the sort of thing you are looking for.

I have provided an example using recursion instead which is the usual way to do this kind of thing in erlang and elixir.

Feel free to ask questions about what I wrote and I will get back to you as quickly as I can. Or if I have mistaken what you are trying to do feel free to elaborate and I will get back to you :slight_smile:

Hope you are enjoying Elixir and stick with it - if it helps I came from a C# background before learning erlang and hit these kind of roadblocks all the time but it’s super rewarding!

3 Likes

defp delete_list([], a, _), do: a

defp delete_list([h | t], a, f) do
case f.(h) do
true -> delete_list(t, a, f)
_ -> delete_list(t, a ++ [h], f)
end
end

def delete_from_list(a, f), do: delete_list(a, [], f)

testing,

f = fn (a) -> fn(x) -> a == x.name end end

delete_from_list [%{name: “a”}, %{name: “b”}, %{name: “c”}], f.(“b”)

1 Like