如何在Elixir(或Erlang)中实现高效的to_ascii
函数?
扫描字符串中的每个字符并调用String.printable?
似乎是 非常 错误选项
def to_ascii(s) do
case String.printable?(s) do
true -> s
false -> _to_ascii(String.codepoints(s), "")
end
end
defp _to_ascii([], acc), do: acc
defp _to_ascii([c | rest], acc) when ?c in 32..127, do: _to_ascii(rest, acc <> c)
defp _to_ascii([_ | rest], acc), do: _to_ascii(rest, acc)
示例:
s_in = <<"hello", 150, " ", 180, "world", 160>>
s_out = "hello world" # valid ascii only i.e 32 .. 127
答案 0 :(得分:6)
使用Kernel.SpecialForms.for/1
理解with :into
keyword argument:
s = "hello привет ¡hola!"
for <<c <- s>>, c in 32..127, into: "", do: <<c>>
#⇒ "hello hola!"
s = <<"hello", 150, "world", 160>>
for <<c <- s>>, c in 32..127, into: "", do: <<c>>
#⇒ "helloworld"
答案 1 :(得分:5)
在Erlang中
1> Bin = <<"hello привет ¡hola!"/utf8>>.
<<104,101,108,108,111,32,208,191,209,128,208,184,208,178,
208,181,209,130,32,194,161,104,111,108,97,33>>
2> << <<C>> || <<C>> <= Bin, C >= 32, C =< 127 >>.
<<"hello hola!">>
3> [ C || <<C>> <= Bin, C >= 32, C =< 127 ].
"hello hola!"