I\'m currently trying to make a Set of all possible combinations from an Array of Strings, were each element contains only one letter.
Here's a Swift 3 function that is a bit faster. It is based on an extension to the Array type that can be used on arrays with any element type.
public func allCombinations(_ array:[String], minLength:Int=2) -> [String]
{
var result:[String] = []
for n in minLength...array.count
{
result = result + array.combinations(of:n).map{ $0.joined(separator:"") }
}
return result
}
extension Array
{
public func combinations(of group:Int) -> [[Element]]
{
if group > count { return [] }
if group == count { return [self] }
var result:[[Element]] = []
var comboIndexes = (0..= 0
{
if carry == fullCombo
{ result.append(comboIndexes.map{self[$0]}) }
comboIndexes[carry] += 1
if comboIndexes[carry] == carry + indexLimit
{ carry -= 1 ; continue }
while carry < fullCombo
{
carry += 1
comboIndexes[carry] = comboIndexes[carry-1] + 1
}
}
return result
}
}
In my tests, it ran about 40x faster than vacawama's second version on 7 letters.
[EDIT] I realized later that this function produces combinations (as requested in the OP) where vacawama's function produces permutations. I tested an equivalent algorithm for permutations and it was merely 55% faster than vacawama's.
extension Array
{
public func permutations(of group:Int? = nil) -> [[Element]]
{
let group = group ?? count
var result : [[Element]] = []
var permutation : [Element] = []
func permute(from baseIndex:Int)
{
if baseIndex == permutation.count - 1
{
result.append(permutation)
return
}
permute(from:baseIndex+1)
for index in baseIndex+1..= 0
{
if carry == fullCombo
{
permutation = comboIndexes.map{self[$0]}
permute(from:0)
}
comboIndexes[carry] += 1
if comboIndexes[carry] == carry + indexLimit
{ carry -= 1 ; continue }
while carry < fullCombo
{
carry += 1
comboIndexes[carry] = comboIndexes[carry-1] + 1
}
}
return result
}
}