这是一个递归解决方案,适用于原始字典中任意数量的键/数组对,以及值数组中的任意数量的值:
let dict = ["A":[1, 2, 3], "B":[4, 5, 6], "C":[7, 8, 9]]
func combine(source: [String : [Int]], partials: [[String : Int]] = [], final: inout [[String : Int]]) {
if source.isEmpty {
// base step of recursion
// there are no more (k:v) pairs in source, so add all of the partials (now final)
// to the final array
final.append(contentsOf: partials)
} else {
// source has a (k:v) pair, so take the first one
let (k, vals) = source.first!
var newsource = source
// remove key from newsource
newsource[k] = nil
// for each value in the key
for val in vals {
// add (k:v) to each partial dictionary
var newpartials = partials
// If new partials array is empty
if newpartials.isEmpty {
// create the array with the first [k:v]
newpartials = [[k : val]]
} else {
// otherwise, add [k:v] to each of the partial dictionaries
for pidx in newpartials.indices {
newpartials[pidx][k] = val
}
}
// recursive call to process the next value in source
combine(source: newsource, partials: newpartials, final: &final)
}
}
}
var result = [[String : Int]]()
combine(source: dict, final: &result)
print(result)
print(result.count)
[[“A”:1,“B”:4,“C”:7],[“A”:2,“B”:4,“C”:7],[“A”:3 , "B": 4, "C": 7], ["C": 7, "B": 5, "A": 1], ["C": 7, "B": 5, "A" : 2], ["C": 7, "B": 5, "A": 3], ["C": 7, "B": 6, "A": 1], ["C": 7 , "B": 6, "A": 2], ["C": 7, "B": 6, "A": 3], ["C": 8, "B": 4, "A" : 1], ["C": 8, "B": 4, "A": 2], ["C": 8, "B": 4, "A": 3], ["C": 8 ,“B”:5,“A”:1],[“C”:8,“B”:5,“A”:2],[“C”:8,“B”:5,“A” : 3], ["B": 6, "C": 8, "A": 1], ["B": 6, "C": 8, "A": 2], ["B": 6 , "C": 8, "A": 3], ["A": 1, "C": 9, "B": 4], ["A": 2, "C": 9, "B" : 4], ["A": 3, "C": 9, "B": 4], ["B": 5, "A": 1, "C": 9], ["B": 5 , "A": 2, "C": 9], ["B": 5, "A": 3, "C": 9], ["B": 6, "A": 1, "C" : 9], ["B": 6, "A": 2, "C": 9], ["B": 6, "A": 3, "C": 9]]
27
通用解决方案
没有理由将其仅限于 String 和 Int。密钥应该是符合Hashable 的任何类型。
要使函数通用,请将签名更改为:
func combine<KEY, VALUE>(source: [KEY : [VALUE]], partials: [[KEY : VALUE]] = [],
final: inout [[KEY : VALUE]]) where KEY: Hashable {
制作Dictionary extension
@LeoDabus 通过在Dictionary 上将其转换为extension 扩展了此答案,其中Value 是Collection(谢谢,Leo!):
extension Dictionary where Value: Collection {
func permutations() -> [[Key: Value.Element]] {
guard !isEmpty else { return [] }
var permutations: [[Key: Value.Element]] = []
permutate(&permutations)
return permutations
}
private func permutate(_ permutations: inout [[Key: Value.Element]], _ dictionaries: [[Key: Value.Element]] = []) {
if let (key, value) = first {
var dictionary = self
dictionary[key] = nil
for element in value {
var dictionaries = dictionaries
if dictionaries.isEmpty {
dictionaries += CollectionOfOne([key: element])
} else {
for index in dictionaries.indices {
dictionaries[index][key] = element
}
}
dictionary.permutate(&permutations, dictionaries)
}
} else {
permutations += dictionaries
}
}
}
let dict = ["A":[1, 2, 3], "B":[4, 5, 6], "C":[7, 8, 9]]
let result = dict.permutations()
print(result)
print(result.count)
[[“B”:4,“A”:1,“C”:7],[“B”:4,“A”:2,“C”:7],[“B”:4 ,“A”:3,“C”:7],[“A”:1,“B”:4,“C”:8],[“A”:2,“B”:4,“C” : 8], ["A": 3, "B": 4, "C": 8], ["A": 1, "B": 4, "C": 9], ["A": 2 , "B": 4, "C": 9], ["A": 3, "B": 4, "C": 9], ["C": 7, "A": 1, "B" : 5], ["C": 7, "A": 2, "B": 5], ["C": 7, "A": 3, "B": 5], ["C": 8 , "A": 1, "B": 5], ["C": 8, "A": 2, "B": 5], ["C": 8, "A": 3, "B" : 5], ["C": 9, "A": 1, "B": 5], ["C": 9, "A": 2, "B": 5], ["C": 9 , "A": 3, "B": 5], ["B": 6, "C": 7, "A": 1], ["B": 6, "C": 7, "A" : 2], ["B": 6, "C": 7, "A": 3], ["B": 6, "A": 1, "C": 8], ["B": 6 , "A": 2, "C": 8], ["B": 6, "A": 3, "C": 8], ["B": 6, "A": 1, "C" : 9], ["B": 6, "A": 2, "C": 9], ["B": 6, "A": 3, "C": 9]]
27