Swift中实现数组无重复组的所有可能组合(含空组合)
Hey there! Let's break down why your current code isn't generating all the 3-element combinations you need, then walk through two solid solutions that'll get you the full set of unique, non-reversed combinations (including the empty array).
What's Wrong With the Current Code?
Your approach works fine for 1 and 2-element groups, but falls apart for larger sizes. The issue is that you're only using two nested loops—you can't build 3+ element groups by just checking index2 > index1 once. For example, to make [1,3,4], you need to pick 1 first, skip 2 to pick 3, then pick 4. Your current logic resets the group back to [item1] after adding one element, so it never gets to add a third element that's further along in the array.
Solution 1: Recursive Approach (Clean & Intuitive)
This method leverages recursion to build combinations by making a simple choice for each element: include it in the current combination, or don't. Since we process elements in order, we never end up with reversed duplicates like [2,1].
public extension Array { func allPossibleCombinations() -> [[Element]] { // Base case: empty array only has one combination (itself) guard !isEmpty else { return [[]] } // Grab the first element and recurse on the rest of the array let first = self[0] let restCombinations = self[1...].allPossibleCombinations() // Create new combinations by adding the first element to every combination from the rest let combinationsWithFirst = restCombinations.map { $0 + [first] } // Combine both sets: combinations without the first element, plus those with it return restCombinations + combinationsWithFirst } }
How It Works:
For [1,2,3,4], we first compute all combinations of [2,3,4]. Then we take each of those combinations and add 1 to them. Merging these two sets gives us every possible combination that either includes 1 or doesn't—no duplicates, no missing groups.
Solution 2: Bitwise Approach (Efficient & Clever)
Every combination can be represented as a binary number where each bit indicates whether we include the corresponding element. For an array of length n, there are 2^n total combinations (including the empty array).
public extension Array { func allPossibleCombinations() -> [[Element]] { let total = 1 << count // Equivalent to 2^count var combinations = [[Element]]() for mask in 0..<total { var combo = [Element]() for index in 0..<count { // Check if the index-th bit in the mask is set to 1 if (mask >> index) & 1 == 1 { combo.append(self[index]) } } combinations.append(combo) } return combinations } }
How It Works:
- For
[1,2,3,4],maskranges from0(binary0000, empty array) to15(binary1111, full array). - A mask like
5(binary0101) means we include elements at indices 0 and 2—so[1,3]. - This method generates combinations in order, so you'll never get reversed duplicates.
Testing the Solutions
Either of these extensions will generate exactly the output you expected for [1,2,3,4]:
[[], [1], [2], [3], [4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 3, 4]]
内容的提问来源于stack exchange,提问作者Danny Bravo

