问题
The other day I asked how could reduce a list of tuples by grouping one of the elements into arrays (F#: Reduce a list of tuples by grouping one of the elements into arrays). I wish now to learn how to do the opposite of this. Lets say I have this:
("A", ["B"; "C"; "D"; "E"])
and I want to get this:
[("A", "B") ; ("A", "C") ; ("A" , "D") ; ("A" , "E")]
What is the functional way to do this? How could I do it with a list of elements of this type to be appended? I have tried:
let prb = ("A", ["B"; "C"; "D"; "E"]) |> [for i in snd -> (fst, i)]
But hasn't worked.
Thanks a lot for your answers! I am new to F# and I am sorry if this is really basic
回答1:
You can use List.map
on snd source
:
let source = ("A", ["B"; "C"; "D"; "E"]);;
// val source : string * string list = ("A", ["B"; "C"; "D"; "E"])
let result = snd source |> List.map (fun x -> fst source, x);;
// val result : (string * string) list =
// [("A", "B"); ("A", "C"); ("A", "D"); ("A", "E")]
Update
For list of these elements
let source = [("A", ["B"; "C"; "D"; "E"]);("A", ["B"; "C"; "D"; "E"]);("A", ["B"; "C"; "D"; "E"])];;
// val source : (string * string list) list =
// [("A", ["B"; "C"; "D"; "E"]); ("A", ["B"; "C"; "D"; "E"]);
// ("A", ["B"; "C"; "D"; "E"])]
you can declare a function with code from above
let collectTuple (x, items) = items |> List.map (fun y -> x, y);;
// val collectTuple : x:'a * items:'b list -> ('a * 'b) list
and use it to call List.map
:
let result = source |> List.map collectTuple;;
// val result : (string * string) list list =
// [[("A", "B"); ("A", "C"); ("A", "D"); ("A", "E")];
// [("A", "B"); ("A", "C"); ("A", "D"); ("A", "E")];
// [("A", "B"); ("A", "C"); ("A", "D"); ("A", "E")]]
or List.collect
if you want just one list of tuples instead:
let result = source |> List.collect collectTuple;;
// val result : (string * string) list =
// [("A", "B"); ("A", "C"); ("A", "D"); ("A", "E"); ("A", "B"); ("A", "C");
// ("A", "D"); ("A", "E"); ("A", "B"); ("A", "C"); ("A", "D"); ("A", "E")]
回答2:
As an alternative to using List.map
, you can also use list comprehensions. For simple transformations, this is usually my preferred option, but this is really just a matter of style, so Marcin's answer is perfectly fine.
The finished version looks like this:
let collectTuple (key, values) =
[ for v in values -> key, v ]
In your attempted solution, you tried to use fst
and snd
to access the elements of the tuple, which works too:
let collectTuple input =
[ for v in snd input -> fst input, v ]
来源:https://stackoverflow.com/questions/25465121/f-expand-a-list-of-tuples-of-form-stringstring-list-list-using-a-key