我是Erlang领域的新手,我正在尝试实现split_binary函数,该函数将(list,index)作为输入,并根据索引将列表拆分为两个列表。
split(Lst, N) when N>=list:lenght(Lst) -> Lst;
split(Lst, N) when N<list:lenght(Lst) -> splitHelper(list:reverse(Lst), 0, N, []).
splitHelper([H|T], X, N, Acc) ->
if
X>=N ->
(list:reverse([H|T]), list:reverse(Acc));
X<N ->
splitHelper(T, X+1, N, [H|Acc])
end.
如何改进我的代码?
2条答案
按热度按时间cidc1ykv1#
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 ofbytes
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: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:which the shell would display as:
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
is0000 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:
[]
means an empty list, and for binaries<<>>
means an empty binary.[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:
In the shell:
Note that when constructing a binary one of the segments of the binary can be another binary:
If you are actually trying to implement lists:split/2, you can do this:
In the shell:
uubf1zoe2#
I think @7stud's answer is the best one, but I wanted to add a few minor details about your code, without actually checking if it works or not…
list:lenght/1
doesn't exist (unless you also created your ownlist
module.list
module, you can't use it in guards. Only BIFs are allowed there.stdlib
's function to check the length of a list, then you should useerlang:length/1
or justlength/1
.snake_case
(e.g.split_helper
) instead ofcamelCase
(e.g.splitHelper
) for module names, function names and atoms in general.if
as the sole expression of your function…{list:reverse([H|T]),…
. BTW… This should have prevented your code from compiling at all. The error should've looked likesyntax error before: ','
list
module, but if not and if you're trying to usestdlib
functionality, it'slists:reverse/1
notlist:reverse/1
.Finally, out of that list, I would strongly recommend you to write some simple tests for your code. This article may help you with that.