F#中是否有库函数合并来自不同列表的元素
Is there a library function in F# Combine elements from different lists
我想要一个函数 f
接受列表的列表和 returns 通过从每个列表中取一个元素而形成的所有可能组合的元组列表。
例如
f [["A";"B";"C"];[1;2]]
会给出结果:
[("A",1);("A",2);("B",1);("B",2);("C",1);("C",2)]
和:
f [[onions;peas];[mash;fries];[chicken;steak]]
会给出:
[(onions,mash,chicken);(onions,mash,steak);(onions;fries;chicken) ... (peas,fries,steak)]
我正在考虑自己动手,但感觉一定有一个库函数比我的拇指拳头方法优化得更好,但我似乎无法通过谷歌搜索找到任何东西(我可能不知道这个的正确组合术语所以继续打不同的组合方法和功能)
F# 标准库中没有 "Cartesian product" 的实现。创建您自己的实现(例如,使用列表理解)非常好。
与 CaringDev 一样,我认为没有任何标准库函数可以执行此操作。我认为原因之一是它们会有不同的类型。
OP 中的 [["A";"B";"C"];[1;2]]
等代码甚至无法编译,因为字符串值的使用向编译器表明这是一个嵌套的字符串列表,但 [1;2]
是一个列表整数。
它可以用元组代替,但这是一对的组合函数与三元组的组合函数不同的地方,依此类推。
也就是说,这些函数实现起来很简单:
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 ]
示例:
> 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")]
其实CaringDev和Mark Seemann说的不太对。尚无库实现,但 F# 4.1 中将有笛卡尔乘积实现(即将推出 TM):https://github.com/Microsoft/visualfsharp/pull/989。可以这样使用:
List.allPairs ["A"; "B"; "C"] [1; 2]
//val it : (string * int) list =
//[("A", 1); ("A", 2); ("B", 1); ("B", 2); ("C", 1); ("C", 2)]
也就是说,它并不能完全解决您的问题,因为它只接受两个列表作为输入,但扩展它应该不会太困难。
我想要一个函数 f
接受列表的列表和 returns 通过从每个列表中取一个元素而形成的所有可能组合的元组列表。
例如
f [["A";"B";"C"];[1;2]]
会给出结果:
[("A",1);("A",2);("B",1);("B",2);("C",1);("C",2)]
和:
f [[onions;peas];[mash;fries];[chicken;steak]]
会给出:
[(onions,mash,chicken);(onions,mash,steak);(onions;fries;chicken) ... (peas,fries,steak)]
我正在考虑自己动手,但感觉一定有一个库函数比我的拇指拳头方法优化得更好,但我似乎无法通过谷歌搜索找到任何东西(我可能不知道这个的正确组合术语所以继续打不同的组合方法和功能)
F# 标准库中没有 "Cartesian product" 的实现。创建您自己的实现(例如,使用列表理解)非常好。
与 CaringDev 一样,我认为没有任何标准库函数可以执行此操作。我认为原因之一是它们会有不同的类型。
OP 中的 [["A";"B";"C"];[1;2]]
等代码甚至无法编译,因为字符串值的使用向编译器表明这是一个嵌套的字符串列表,但 [1;2]
是一个列表整数。
它可以用元组代替,但这是一对的组合函数与三元组的组合函数不同的地方,依此类推。
也就是说,这些函数实现起来很简单:
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 ]
示例:
> 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")]
其实CaringDev和Mark Seemann说的不太对。尚无库实现,但 F# 4.1 中将有笛卡尔乘积实现(即将推出 TM):https://github.com/Microsoft/visualfsharp/pull/989。可以这样使用:
List.allPairs ["A"; "B"; "C"] [1; 2]
//val it : (string * int) list =
//[("A", 1); ("A", 2); ("B", 1); ("B", 2); ("C", 1); ("C", 2)]
也就是说,它并不能完全解决您的问题,因为它只接受两个列表作为输入,但扩展它应该不会太困难。