String 如何在Elixir中循环遍历字符串中的每个字符?
假设我在一个字符串中存储了大量的文本~500个字符,我如何在字符串中循环并在每次遇到字符“a”时将变量递增1?我对代码的理解是:String 如何在Elixir中循环遍历字符串中的每个字符?,string,loops,functional-programming,elixir,String,Loops,Functional Programming,Elixir,假设我在一个字符串中存储了大量的文本~500个字符,我如何在字符串中循环并在每次遇到字符“a”时将变量递增1?我对代码的理解是: countSubstring = fn(_, "") -> 0 (str, sub) -> length(String.split(str, sub)) - 1 end 您可以使用IO.puts countSubstring.(str,“a”)调用。我认为有一些更容易理解的方法可能适合您。使用正则表达式: Regex.s
countSubstring = fn(_, "") -> 0
(str, sub) -> length(String.split(str, sub)) - 1 end
您可以使用IO.puts countSubstring.(str,“a”)调用。我认为有一些更容易理解的方法可能适合您。使用正则表达式:
Regex.scan(~r/a/, str) |> Enum.count
或者将字符串划分为unicode字符,然后计算:
str |> String.graphemes |> Enum.count(fn(c) -> c == "a" end)
这些都不是非常有效的方法,但是对于长度只有500个字符的字符串(相对较小!),性能影响应该可以忽略不计
如果您需要更有效的方法,一个好的选择通常是使用递归进行迭代,然后手动计算发生次数。尽管这种方法非常冗长,但它的性能要好得多
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
欢迎来到堆栈溢出!你已经试着自己解决这个问题了吗?如果是的话,你到底是在哪里被卡住的?一般来说,人们对“请为我编写此代码”请求(看起来像这样)的响应不太好,但对“我尝试了此方法,现在我卡住了/困惑了,请帮助”请求的响应很好;-)500个字符是小的,不是大的。在500个字符的情况下,很难找到一种不好的方法来检查字符串。这很好,你能解释一下它是如何工作的吗?我不明白它如何跟踪参数中每个“”的计数。抱歉,我不习惯Elixir这是我的第一个项目,语法对我来说不是很友好:尽管这不是最直观的解决方案,但它的性能非常好,还可以处理多个字符。请参阅我答案中的基准测试。快速回顾一下涉及匿名函数的语法。简言之,Elixir函数(包括匿名函数)可以定义多个签名,调用的版本基于模式匹配和/或门。第一个变量处理输入子字符串为空的情况。第二个处理其他用例——String.split()返回一个列表,该列表的大小减去1对应于子字符串的出现。希望有帮助。
# 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