在您的输出示例中,您也不清楚您真正想要什么:
-
它们的所有组合和排列:
["AB", "BA", "AC", "CA", "AD", "DA", ..., "ABCD", "ABDC", "ACBD", "ACDB", ...]
-
只是所有组合:
["AB", "AC", "AD", "BC", "BD", "CD", "ABC", "ABD", ...]
我可以为他们推荐@oisdk 的优秀 Swift 库:SwiftSequence,它有很多有用的功能。在组合部分,他甚至展示了它与Power Set 一起使用的示例,这几乎正是您在案例 1 中所要查找的内容。导入他的库文件后,您可以在 @ 上创建 powerSet 函数987654326@s 这样的:
extension CollectionType {
func powerSet() -> LazySequence<FlattenSequence<LazyMapSequence<Self, ComboSeq<Self.Generator.Element>>>>{
var i = 0
return lazy.flatMap{ _ in self.lazyCombos(++i) }
}
}
此方法延迟评估,这意味着它仅在真正需要时才评估。现在您提到您只想拥有至少 2 个元素的组合。这可以通过filter 方法轻松完成:
let combinations = ["A", "B", "C", "D"].powerSet().filter{ $0.count >= 2 }
// As an array: [["A", "B"], ["A", "C"], ["A", "D"], ["B", "C"], ["B", "D"], ["C", "D"], ["A", "B", "C"], ["A", "B", "D"], ["A", "C", "D"], ["B", "C", "D"], ["A", "B", "C", "D"]]
对于情况 2。如果您还需要这些排列,您可以这样做:
let combPerms = combinations.flatMap{ $0.permutations() }
// As an array: [["A", "B"], ["B", "A"], ["A", "C"], ["C", "A"], ["A", "D"], ["D", "A"], ["B", "C"], ["C", "B"], ["B", "D"], ["D", "B"], ["C", "D"], ["D", "C"], ["A", "B", "C"], ["A", "C", "B"], ["B", "A", "C"], ["B", "C", "A"], ["C", "A", "B"], ["C", "B", "A"], ["A", "B", "D"], ["A", "D", "B"], ["B", "A", "D"], ["B", "D", "A"], ["D", "A", "B"], ["D", "B", "A"], ["A", "C", "D"], ["A", "D", "C"], ["C", "A", "D"], ["C", "D", "A"], ["D", "A", "C"], ["D", "C", "A"], ["B", "C", "D"], ["B", "D", "C"], ["C", "B", "D"], ["C", "D", "B"], ["D", "B", "C"], ["D", "C", "B"], ["A", "B", "C", "D"], ["A", "B", "D", "C"], ["A", "C", "B", "D"], ["A", "C", "D", "B"], ["A", "D", "B", "C"], ["A", "D", "C", "B"], ["B", "A", "C", "D"], ["B", "A", "D", "C"], ["B", "C", "A", "D"], ["B", "C", "D", "A"], ["B", "D", "A", "C"], ["B", "D", "C", "A"], ["C", "A", "B", "D"], ["C", "A", "D", "B"], ["C", "B", "A", "D"], ["C", "B", "D", "A"], ["C", "D", "A", "B"], ["C", "D", "B", "A"], ["D", "A", "B", "C"], ["D", "A", "C", "B"], ["D", "B", "A", "C"], ["D", "B", "C", "A"], ["D", "C", "A", "B"], ["D", "C", "B", "A"]]
您可以将这些转换为 Set 或 Strings 或 Array:
let array = Array(combPerms)
let set = Set(combPerms)
但我强烈建议使用惰性版本 ;) 是的,要删除重复项,您只需使用 Set(["A", "B", "C", "D"]) 而不是 ["A", "B", "C", "D"]
您也可以像这样一次性完成案例 2:
let x = ["A", "B", "C", "D"]
let result = Set(
x.indices
.flatMap{ x.lazyCombos($0 + 1) }
.filter{ $0.count >= 2 }
.flatMap{ $0.permutations() }
.map{ $0.joinWithSeparator("") })