Erlang:在每个char上拆分二进制文件

时间:2017-05-26 14:23:03

标签: erlang

我编写了一个有效的函数,将二进制文件拆分为每个字符,但我觉得有一种更简单的方法:

my_binary_to_list(<<H,T/binary>>) ->
%slightly modified version of http://erlang.org/doc/efficiency_guide/binaryhandling.html
    [list_to_binary([H])|my_binary_to_list(T)];
my_binary_to_list(<<>>) -> [].

> my_binary_to_list(<<"ABC">>).
[<<"A">>,<<"B">>,<<"C">>]

我认为这可能因为list_to_binary([H])而导致凌乱,因为H应该已经是二进制文件。

我尝试直接使用该链接功能但获得了"AA"这不是我想要的。然后我尝试了[H]并获得了["A","B","C"]这也不是我想要的。

2 个答案:

答案 0 :(得分:8)

您可以从单个字节创建二进制文件,而无需创建列表并像这样调用list_to_binary

my_binary_to_list(<<H,T/binary>>) ->
    [<<H>>|my_binary_to_list(T)];

您也可以在这里使用二元理解来在一行中执行与上述相同的逻辑:

1> [<<X>> || <<X>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]

你也可以直接提取大小为1的二进制文件(虽然这可能不比上面快):

2> [X || <<X:1/binary>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]

编辑:使用timer:tc/1的快速工作台在大约一半的时间内运行第二个代码,但是出于性能原因,您应该在使用任何一个代码之前对自己进行基准测试。也许第二个是通过创建子二进制文件来共享大二进制文件?

1> Bin = binary:copy(<<"?">>, 1000000).
<<"????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"...>>
2> timer:tc(fun() -> [<<X>> || <<X>> <= Bin] end).
{14345634,
 [<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
  <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
  <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
  <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
3> timer:tc(fun() -> [X || <<X:1/binary>> <= Bin] end).
{7374003,
 [<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
  <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
  <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
  <<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}

答案 1 :(得分:3)

您可以将列表推导与位字符串生成器一起使用(<=使用二进制文件,而不是消耗列表的<-):

> [<<A>> || <<A>> <= <<"foo">>].
[<<"f">>,<<"o">>,<<"o">>]

在您的版本中,list_to_binary([H])可以替换为<<H>> - 两者都生成包含一个字节的二进制文件。是否使用列表推导而不是递归函数符合&#34;更容易&#34;可能是品味问题。