# implementation of the splitting binary function of erlang

I’m new in the Erlang world. I’m trying to implement the function split_binary. The function takes as input (list, index) and it splits the list in two lists according to the index.

According to the erlang docs for split_binary/2, the two arguments are a `binary`, which is not a list, and the number of `bytes` where you want to split the binary.

First, you need to have a basic understanding of what a binary is. A binary is a sequence of bytes, where each byte is 8 bits representing some integer, e.g.

`0010 0001`

which is `33`. Here is an example of a binary:

``````<<1, 2, 3>>
``````

When you don’t specify a size for each integer, by default each integer will occupy one byte. If you wanted the `2` to occupy two bytes instead, i.e. `0000 0000 0000 0010`, which is 16 bits, then you could write:

``````<<1, 2:16, 3>>
``````

which the shell would display as:

`````` <<1,0,2,3>>
``````

Huh? Where did that 0 come from? The shell displays a binary byte by byte, and the first byte of the integer `0000 0000 0000 0010` is `0000 0000`, which is 0.

Next, you can step through a binary just like you can for a list, extracting any number of bits at a time from the front of the binary. It so happens that `split_binary/2` extracts 8 bits, or 1 byte, at a time from the head of the binary.

There are a couple of tricks to learning how to step through a binary:

1. For lists, `[]` means an empty list, and for binaries `<<>>` means an empty binary.

2. For lists you write `[Head|Tail]` to extract the head of the list, and for binaries you write `<<Bits:3, Rest/binary>>` to extract 3 bits from the front of the binary. In your case, you need to extract 8 bits from the front of the binary.

Here is an example of what you can do:

``````-module(a).
-compile(export_all).

split_b(Bin, N) ->
split_b(Bin, N, _Acc = <<>>).

split_b(     Bin,               _N = 0, Acc) -> [Acc, Bin];
split_b(<<Bits:8, Rest/binary>>, N,     Acc) ->
split_b(Rest, N-1, <<Acc/binary, Bits>>).
``````

In the shell:

``````40> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

41> a:split_b(<<5,6,7>>, 1).
[<<5>>,<<6,7>>]

42> a:split_b(<<5,6,7>>, 2).
[<<5,6>>,<<7>>]
``````

Note that when constructing a binary one of the segments of the binary can be another binary:

``````23> Bin = <<1, 2, 3>>.
<<1,2,3>>

24> Acc = <<Bin/binary, 4>>.
<<1,2,3,4>>
``````

If you are actually trying to implement lists:split/2, you can do this:

``````-module(a).
-compile(export_all).

split_l(N, List) ->
split_l(N, List, _Acc=[]).

split_l(_N=0, List, Acc) ->
[lists:reverse(Acc), List];
split_l(N, [H|T], Acc) ->
split_l(N-1, T, [H|Acc]).
``````

In the shell:

``````2> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}

3> a:split_l(1, [10, 20, 30]).
["\n",[20,30]]

4> shell:strings(false).
true

5> a:split_l(1, [10, 20, 30]).
[[10],[20,30]]

6> a:split_l(2, [10, 20, 30]).
[[10,20],[30]]
``````

CLICK HERE to find out more related problems solutions.

Scroll to Top