Short answer
let crossJoin xs ys =
xs
|> Seq.map (fun x -> ys |> Seq.map (fun y -> (x, y)))
|> Seq.concat
let group f xs ys = ys |> crossJoin xs |> Seq.groupBy f
Longer answer
, , , :
let crossJoin xs ys =
xs
|> Seq.map (fun x -> ys |> Seq.map (fun y -> (x, y)))
|> Seq.concat
, , :
let integers = [0 .. 10] |> List.toSeq
let strings = [0 .. 5] |> Seq.map string
:
> crossJoin integers strings |> Seq.toList;;
val it : (int * string) list =
[(0, "0"); (0, "1"); (0, "2"); (0, "3"); (0, "4"); (0, "5"); (1, "0");
(1, "1"); (1, "2"); (1, "3"); (1, "4"); (1, "5"); (2, "0"); (2, "1");
(2, "2"); (2, "3"); (2, "4"); (2, "5"); (3, "0"); (3, "1"); (3, "2");
(3, "3"); (3, "4"); (3, "5"); (4, "0"); (4, "1"); (4, "2"); (4, "3");
(4, "4"); (4, "5"); (5, "0"); (5, "1"); (5, "2"); (5, "3"); (5, "4");
(5, "5"); (6, "0"); (6, "1"); (6, "2"); (6, "3"); (6, "4"); (6, "5");
(7, "0"); (7, "1"); (7, "2"); (7, "3"); (7, "4"); (7, "5"); (8, "0");
(8, "1"); (8, "2"); (8, "3"); (8, "4"); (8, "5"); (9, "0"); (9, "1");
(9, "2"); (9, "3"); (9, "4"); (9, "5"); (10, "0"); (10, "1"); (10, "2");
(10, "3"); (10, "4"); (10, "5")]
crossJoin :
let group f xs ys = ys |> crossJoin xs |> Seq.groupBy f
:
> group (fun (x, y) -> x.ToString() = y) integers strings |> Seq.toList;;
val it : (bool * seq<int * string>) list =
[(true, seq [(0, "0"); (1, "1"); (2, "2"); (3, "3"); ...]);
(false, seq [(0, "1"); (0, "2"); (0, "3"); (0, "4"); ...])]
, true, false.
, , , :
> group (fun (x, y) -> x.ToString() = y) integers strings |> Seq.filter fst |> Seq.head |> snd |> Seq.toList;;
val it : (int * string) list =
[(0, "0"); (1, "1"); (2, "2"); (3, "3"); (4, "4"); (5, "5")]
Seq.iter Seq.map .
, .
, , .