Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten a list of nested lists in Erlang

Tags:

list

erlang

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 solve flatten.

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?

like image 716
Vayn Avatar asked Feb 18 '12 22:02

Vayn


People also ask

What are the two types of lists available in Erlang?

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.


1 Answers

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]) .
like image 143
Odobenus Rosmarus Avatar answered Nov 14 '22 12:11

Odobenus Rosmarus