0
votes

I'm trying to implement a dictionary but the Map.put function is not adding the new element to the map instead it is giving me a new map with the last (key, value} inserted I also tried Map.put_new it did not work

def someFunction(array) do

    dict = %{}

    Enum.each(array, fn item ->
        if (Map.has_key?(dict, item)) do
            dict = %{dict | item => (dict[item] + 1)}
        else
            dict = Map.put(dict , item, 1)
        end
    end)

end
1

1 Answers

7
votes

The way elixir does variable scopes, you can't set dict from inside your Enum.each/2. Instead what you need to do is pass dict as an accumulator while enumerating array.

dict =
  Enum.reduce(array, %{}, fn item, dict ->
    if (Map.has_key?(dict, item)) do
      %{dict | item => (dict[item] + 1)}
    else
      Map.put(dict , item, 1)
    end
  end)

You can also use Map.update/4 to improve your reducer.

dict = Enum.reduce(array, %{}, fn item, dict -> Map.update(dict, item, 1, &(&1 + 1)) end)

But there's actually a built-in function since Elixir 1.10, Enum.frequencies/1.

dict = Enum.frequencies(array)