I'm working on the exercises in Erlang Programming.
The question is
Write a function that, given a list of nested lists, will return a flat list.
Example:
flatten([[1,[2,[3],[]]], [[[4]]], [5,6]]) ⇒ [1,2,3,4,5,6].
Hint: use
concatenate
to solveflatten
.
And here is my concatenate
function
%% concatenate([[1,2,3], [], [4, five]]) ⇒ [1,2,3,4,five].
concatenate([X|Xs]) -> concat(X, Xs, []).
concat([X|Xs], T, L) -> concat(Xs, T, [X|L]);
concat([], [X|Xs], L) -> concat(X, Xs, L);
concat([], [], L) -> reverse(L).
I really want to know an elegant way to implement flatten
. I've spent hours solving this exercise.
UPDATE: I forget most important prerequisite. Is it possible solving this problem with only recursion and pattern matching?
You can't seriously program in a language just with scalar types like numbers, strings and atoms. For this reason, now that we have a basic knowledge of Erlang's syntax and variables, we have to delve into two basic vector types: tuples and lists.
I would try this way
flatten(X) -> lists:reverse(flatten(X,[])).
flatten([],Acc) -> Acc;
flatten([H|T],Acc) when is_list(H) -> flatten(T, flatten(H,Acc));
flatten([H|T],Acc) -> flatten(T,[H|Acc]).
testing
my:flatten([[1,[2,[3],[]]], [[[4]]], [5,6]]).
[1,2,3,4,5,6]
UPD: or this way, without guards and reverse, only recursive calls and pattern matching.
flatten(X) -> flatten(X,[]).
flatten([],Acc) -> Acc;
flatten([[]|T],Acc) -> flatten(T, Acc);
flatten([[_|_]=H|T],Acc) -> flatten(T, flatten(H,Acc));
flatten([H|T],Acc) -> flatten(T,Acc++[H]) .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With