Reputation: 13632
I wrote a function that works, to split a binary to every char, but I have a feeling there is an easier way to do it:
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">>]
I think this is probably messy because of the list_to_binary([H])
because H
should already be a binary.
I tried using that linked function directly but got "AA"
which was not what I wanted. Then I tried just [H]
and got ["A","B","C"]
which was also not what I wanted.
Upvotes: 2
Views: 311
Reputation: 222088
You can create a binary from a single byte without creating a list and calling list_to_binary
like this:
my_binary_to_list(<<H,T/binary>>) ->
[<<H>>|my_binary_to_list(T)];
You can also use binary comprehensions here to do the same logic as above in a single line:
1> [<<X>> || <<X>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]
You can also directly extract binaries of size 1 (this is probably not faster than above though):
2> [X || <<X:1/binary>> <= <<"ABC">>].
[<<"A">>,<<"B">>,<<"C">>]
Edit: a quick bench using timer:tc/1
runs the second code in roughly half the time compared to first, but you should benchmark yourself before using either one for performance reasons. Maybe the second one is sharing the large binary by creating sub binaries?
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,
[<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,
<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<"?">>,<<...>>|...]}
Upvotes: 7
Reputation: 41528
You can use a list comprehension with a bit string generator (<=
consumes binaries, as opposed to <-
which consumes lists):
> [<<A>> || <<A>> <= <<"foo">>].
[<<"f">>,<<"o">>,<<"o">>]
In your version, list_to_binary([H])
can be replaced by <<H>>
- both generate a binary containing one byte. Whether using a list comprehension instead of a recursive function qualifies as "easier" might be a matter of taste.
Upvotes: 2