Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I loop through each character in a string in Elixir? [closed]

Say I have a huge body of text ~500 chars stored in a string, how can i loop through the string and increment a variable by 1 every time i encounter the character 'a'?

like image 850
frostmage Avatar asked Apr 03 '16 01:04

frostmage


People also ask

How to loop on every character in string in C++?

Program to loop on every character in string in C++. Here in this program we will see how to iterate through each characters of a string in C++. To loop on each character, we can use loops starting from 0 to (string length – 1). For accessing the character we can either use subscript operator " [ ]" or at () function of string object.

How to iterate through each character of a string in C++?

Here in this program we will see how to iterate through each characters of a string in C++. To loop on each character, we can use loops starting from 0 to (string length – 1).

How do you loop through a string in a MsgBox?

Loop Through Each Character in a String. The following is an example of looping through a string using a For…Next Loop, and returning each character in a msgbox. The Len Function counts the total number of characters in the string. will loop through each letter in the string.

How to access each character of a string using for-loop?

In the above example, we have used the for-loop to access each element of the string. Here, we have used the charAt () method to access each character of the string. In the above example, we have converted the string into a char array using the toCharArray ().


2 Answers

I think there are more easily understandable approaches to this that might work just fine for you. Using a regex:

Regex.scan(~r/a/, str) |> Enum.count

or dividing the string into its unicode characters and then counting on that:

str |> String.graphemes |> Enum.count(fn(c) -> c == "a" end)

These are not very efficient approaches but the performance impact should be negligible with a (relatively small!) string that is only 500 chars long.

If you need a more efficient approach, a good option is often to iterate using recursion and then counting the occurences manually. Although this approach is quite verbose, it performs much better.

defmodule Recursive do
  def count(str, <<c::utf8>>) do
    do_count(str, c, 0)
  end

  defp do_count(<<>>, _, acc) do
    acc
  end

  defp do_count(<<c::utf8, rest::binary>>, c, acc) do
    do_count(rest, c, acc + 1)
  end

  defp do_count(<<_::utf8, rest::binary>>, c, acc) do
    do_count(rest, c, acc)
  end
end

Finally, here's a benchmark using benchfella of the approaches so far. I also included @DeboraMartins' "split length" solution, which outperforms all of the above for small strings. For larger strings, the difference to the recursive approach is negligible.

# 500 Characters

split length         500000   5.90 µs/op
recursive            100000   10.63 µs/op
regex count          100000   24.35 µs/op
graphemes count       10000   118.29 µs/op


# 500.000 Characters

split length            100   11150.59 µs/op
recursive               100   12002.20 µs/op
regex count             100   25313.40 µs/op
graphemes count          10   218846.20 µs/op
like image 56
Patrick Oscity Avatar answered Sep 22 '22 10:09

Patrick Oscity


My sugestion of code is:

countSubstring = fn(_, "") -> 0
                 (str, sub) -> length(String.split(str, sub)) - 1 end

And you can call using IO.puts countSubstring.(str, "a")

like image 39
Debora Martins Avatar answered Sep 23 '22 10:09

Debora Martins