Reputation: 51
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
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
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