【发布时间】:2010-10-04 04:06:48
【问题描述】:
我一直在寻找一种优雅的方式来编写一个函数,该函数接受一个元素列表并返回一个包含所有可能的不同元素对的元组列表,而不考虑顺序,即 (a,b) 和 ( b,a) 应该被认为是相同的,并且只返回其中一个。 我确信这是一个非常标准的算法,它可能是 F# 文档封面页中的一个示例,但我找不到它,甚至没有在 Internet 上搜索 SML 或 Caml。我想出的是以下内容:
let test = [1;2;3;4;5;6]
let rec pairs l =
seq {
match l with
| h::t ->
yield! t |> Seq.map (fun elem -> (h, elem))
yield! t |> pairs
| _ -> ()
}
test |> pairs |> Seq.toList |> printfn "%A"
这可行并返回预期结果[(1, 2); (1, 3); (1, 4); (1, 5); (1, 6); (2, 3); (2, 4); (2, 5); (2, 6); (3, 4); (3, 5); (3, 6); (4, 5); (4, 6); (5, 6)] 但它看起来非常单调。 我应该不需要遍历序列表达式然后再转换回列表,必须有一个仅涉及基本列表操作或库调用的等效解决方案...
已编辑:
我这里也有这个
let test = [1;2;3;4;5;6]
let rec pairs2 l =
let rec p h t =
match t with
| hx::tx -> (h, hx)::p h tx
| _ -> []
match l with
| h::t -> p h t @ pairs2 t
| _ -> []
test |> pairs2 |> Seq.toList |> printfn "%A"
同样有效,但与第一个一样,考虑到相当简单的问题,它似乎不必要地涉及和复杂。我想我的问题是关于风格的,真的,如果有人可以为此想出一个两条线。
【问题讨论】:
-
糟糕,在我进行编辑时,人们已经发布了建议。谢谢大家,你们都这么快!
标签: f#