Reputation: 1189
Is it possible and if so, how could I use binary comprehension on Elixir? I can do it on Erlang like so:
[One || <<One, _rest:3/binary>> <= <<1,2,3,4>>].
Upvotes: 4
Views: 1435
Reputation: 13154
What in Erlang is:
1> [Red || <<Red:2/binary, _Blue:2/binary>> <= <<1, 2, 3, 4, 5, 6, 7, 8>> ].
[<<1,2>>,<<5,6>>]
In Elixir is:
iex(1)> for <<red::8, green::8, blue::16 <- <<1, 2, 3, 4, 5, 6, 7, 8>> >>, do: <<red, green>>
[<<1, 2>>, <<5, 6>>]
Note that the Elixir above is explicitly declaring sizes in bits, whereas the Erlang is using a type for make the calculation chop off a size in bytes. There is probably a cleaner way to do that in Elixir (at least I hope there is) and I might even hunt around for it -- but most of the time when I want to do this stuff extensively I stick to Erlang just for readability/universality.
Addendum
@aronisstav asked an interesting question: "Shouldn't there be a part matching the green
pattern in the Erlang code?"
The answer is that there would be a Green
variable in Erlang were that code to deal with bitstrings instead of binaries. Erlang's bit syntax provides ways to indicate a few arbitrary binary types which correspond to default sizes. Above I matched Red:2/binary
which means I want to match a sequence of 2 bytes, and this is how we get the result [<<1,2>><<5,6>>]
: two sequences of two bytes.
An Erlang example that is exactly equivalent to the Elixir code above would be:
[<<Red/bitstring, Green/bitstring>>
|| <<Red:8/bitstring, Green:8/bitstring, _Blue:2/binary>>
<= <<1, 2, 3, 4, 5, 6, 7, 8>> ].
But that is just silly to do, as Erlang's syntax for bytes is much more concise.
Upvotes: 4
Reputation: 1189
I found the solution in the documentation:
for << one, _rest :: binary - size(3) <- <<1,2,3,4>> >>, do: one
Upvotes: 1