Malte
Malte

Reputation: 51

Cartesian Product of a list of lists in Erlang

I have a list of lists (in erlang, strings are lists) which looks like this:

["abc","def"]

and I would like to get the following combinations in a list returned by a function:

["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]

Is it possible with list-comprehension? I don't know the dimension of the list beforehand

Upvotes: 2

Views: 947

Answers (2)

Kijewski
Kijewski

Reputation: 26043

If you don't know the dimension of the input, then you need to use recursion as @legoscia said:

cartesian([H])   -> [[A] || A <- H];
cartesian([H|T]) -> [[A|B] || A <- H, B <- cartesian(T)].

A 1-dim input "abc" is turned into ["a", "b", "c"], everything else is recursion.

> cartesian:cartesian(["abc", "def", "ghi"]).
 ["adg","adh","adi","aeg","aeh","aei","afg","afh","afi",
 "bdg","bdh","bdi","beg","beh","bei","bfg","bfh","bfi","cdg",
 "cdh","cdi","ceg","ceh","cei","cfg","cfh","cfi"]

Edit: Or easier, yet: Let a 0-dim argument return the set that contains the empty set. I think that's what a mathematician would do, too.

cartesian([H|T]) -> [[A|B] || A <- H, B <- cartesian(T)];
cartesian([]) -> [[]].

Upvotes: 9

legoscia
legoscia

Reputation: 41618

If you have exactly two lists, then you can do it with a list comprehension like this:

1> [[X,Y] || X <- "abc", Y <- "def"].
["ad","ae","af","bd","be","bf","cd","ce","cf"]

If you have an arbitrary number of lists, you could do it with a list comprehension inside a recursive function.

Upvotes: 3

Related Questions