Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a library function in F# Combine elements from different lists

I want a function f that takes a list of lists and returns the list of tuples of all possible combinations made by taking one element from each list.

For example

f [["A";"B";"C"];[1;2]]

would give the result:

[("A",1);("A",2);("B",1);("B",2);("C",1);("C",2)]

and:

f [[onions;peas];[mash;fries];[chicken;steak]]

would give:

[(onions,mash,chicken);(onions,mash,steak);(onions;fries;chicken) ... (peas,fries,steak)]

I am contemplating rolling my own but feel like there MUST be a library function somewhere much better optimised than my thumb-fisted approach but I cannot seem to find anything by googling (I may not know the correct combinatoric term for this so keep hitting different combination methods & functions)

like image 431
Stewart_R Avatar asked Dec 07 '22 20:12

Stewart_R


1 Answers

Like CaringDev, I don't think that there are any standard library functions that do this. One of the reasons, I think, is that they would have different types.

Code such as [["A";"B";"C"];[1;2]] from the OP doesn't even compile, because the use of string values indicates to the compiler that this is a nested list of strings, but [1;2] is a list of integers.

It can be done with tuples instead, but this is where a combinatorial function for a pair would be different from one for a triplet, and so on.

That said, such functions are trivial to implement:

let combine2 xs ys = [
    for x in xs do
    for y in ys do
    yield x, y ]

let combine3 xs ys zs = [
    for x in xs do
    for y in ys do
    for z in zs do
    yield x, y, z ]

Examples:

> combine2 ["A";"B";"C"] [1;2];;
val it : (string * int) list =
  [("A", 1); ("A", 2); ("B", 1); ("B", 2); ("C", 1); ("C", 2)]
> combine3 ["onions"; "peas"] ["mash"; "fries"] ["chicken"; "steak"];;
val it : (string * string * string) list =
  [("onions", "mash", "chicken"); ("onions", "mash", "steak");
   ("onions", "fries", "chicken"); ("onions", "fries", "steak");
   ("peas", "mash", "chicken"); ("peas", "mash", "steak");
   ("peas", "fries", "chicken"); ("peas", "fries", "steak")]
like image 58
Mark Seemann Avatar answered May 24 '23 13:05

Mark Seemann