如何在Elixir/Erlang中实现高效的to_ascii函数

Cha*_*gwu 1 erlang ascii elixir

如何to_ascii在Elixir(或Erlang)中实现高效的功能?

扫描字符串的每个字符并调用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)
Run Code Online (Sandbox Code Playgroud)

例:

s_in = <<"hello", 150, " ", 180, "world", 160>>
s_out = "hello world" # valid ascii only i.e 32 .. 127
Run Code Online (Sandbox Code Playgroud)

Ale*_*kin 6

使用带有关键字参数的Kernel.SpecialForms.for/1理解::into

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"
Run Code Online (Sandbox Code Playgroud)

  • 这显然不是我; 责怪何塞:) (3认同)

Hyn*_*dil 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!"
Run Code Online (Sandbox Code Playgroud)