A type that computes combinations of a collection’s elements.
The combinations(ofCount:) method returns a sequence of all the different
combinations of a collection’s elements, with each combination in the order of
the original collection.
let numbers = [10, 20, 30, 40]
for combo in numbers.combinations(ofCount: 2) {
print(combo)
}
// [10, 20]
// [10, 30]
// [10, 40]
// [20, 30]
// [20, 40]
// [30, 40]The combinations of elements are presented in increasing lexicographic order of the collection’s original ordering. Values that are repeated in the original collection are always treated as separate values in the resulting combinations:
let numbers2 = [20, 10, 10]
for combo in numbers2.combinations(ofCount: 2) {
print(combo)
}
// [20, 10]
// [20, 10]
// [10, 10]Given a range, the combinations(ofCount:) method returns a sequence of all
the different combinations of the given sizes of a collection’s elements in
increasing order of size.
let numbers = [10, 20, 30, 40]
for combo in numbers.combinations(ofCount: 2...3) {
print(combo)
}
// [10, 20]
// [10, 30]
// [10, 40]
// [20, 30]
// [20, 40]
// [30, 40]
// [10, 20, 30]
// [10, 20, 40]
// [10, 30, 40]
// [20, 30, 40]The combinations(ofCount:) method is declared as a Collection extension,
and returns a CombinationsSequence type:
extension Collection {
public func combinations(ofCount k: Int) -> CombinationsSequence<Self>
}Since the CombinationsSequence type needs to store an array of the
collection’s indices and mutate the array to generate each permutation,
CombinationsSequence only has Sequence conformance. Adding Collection
conformance would require storing the array in the index type, which would in
turn lead to copying the array at every index advancement.
CombinationsSequence does conform to LazySequenceProtocol when the base type
conforms.
Calling combinations(ofCount:) accesses the count of the collection, so it’s
an O(1) operation for random-access collections, or an O(n) operation
otherwise. Creating the iterator for a CombinationsSequence instance and each
call to CombinationsSequence.Iterator.next() is an O(n) operation.
The parameter label in combination(ofCount:) is the best match for the
Swift's API Design Guidelines. A few other options were considered:
- When the standard library uses
ofas a label, the parameter is generally the object of the operation, as intype(of:)andfirstIndex(of:), and not a configuration detail. - The
countlabel typically indicates the count of the resulting collection, as in therepeatElement(_:count:)function or theString(repeating:count:)initializer. kis used a term of art for combinations and permutations, but isn't widely used in programming contexts.
Rust/Ruby/Python: Rust, Ruby, and Python all define functions with essentially the same semantics as the method described here.