Q:

Counting number of occurrence of each char (Elixir)?

In JS, I can do something like this:
function countIt(str){
  let obj = {};
  for(let i = 0; i < str.length; i++){
    if(!obj[str[i]]){
      obj[str[i]] = 1;
    } else {
      obj[str[i]]++;
    }
  }
  return obj;
}

console.log(countIt("hello"));
//returns {
  e: 1,
  h: 1,
  l: 2,
  o: 1
}

What is the best way to count the occurrence of each character with Map in Elixir considering its immutability? What is the general strategy for functional languages to solve this type of problem?

A:

What is the general strategy for functional languages to solve this type of problem?

Enum.reduce/3
"Hello World"
|> String.graphemes()
|> Enum.reduce(%{}, fn char, acc ->
     Map.put(acc, char, (acc[char] || 0) + 1)
   end)
#⇒ %{" " => 1, "H" => 1, "W" => 1, "d" => 1,
#    "e" => 1, "l" => 3, "o" => 2, "r" => 1}

or (credits to @Dogbert) using Map.update/4:
"Hello World"
|> String.graphemes()
|> Enum.reduce(%{}, fn char, acc ->
     Map.update(acc, char, 1, &(&1 + 1))
   end)

Or, maybe more idiomatic, based on pattern matching reducer arguments to determine whether we should add or initiate the counter:
"Hello World"
|> String.graphemes()
|> Enum.reduce(%{}, fn char, acc ->
     case acc do
       %{^char => count} -> %{acc | char => count + 1}
       _ -> Map.put(acc, char, 1)
     end
   end)

