Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all possible combination of items in array without duplicate groups in Swift

I'm trying to create an extension on Array where I can get all possible combinations of an array without generating duplicate groups, including a no item combination.

For example, for this array:

[1, 2, 3, 4]

The following possible combinations should be generated:

[[], [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]]

Please note that none of the groups repeat themselves, i.e: if there is a group [1, 2] there is no other group: [2, 1].

This is the closest I've been able to get to a result:

public extension Array {

func allPossibleCombinations() -> [[Element]] {
    var output: [[Element]] = [[]]
    for groupSize in 1...self.count {
        for (index1, item1) in self.enumerated() {
            var group = [item1]
            for (index2, item2) in self.enumerated() {
                if group.count < groupSize {
                    if index2 > index1 {
                        group.append(item2)
                        if group.count == groupSize {
                            output.append(group)
                            group = [item1]
                            continue
                        }
                    }
                } else {
                    break
                }
            }
            if group.count == groupSize {
                output.append(group)
            }
        }
    }
    return output
}

}

But it is missing possible combination of items in the group size 3 (I only get back [1, 2, 3] and [2, 3, 4].

Much appreciated!

like image 228
Danny Bravo Avatar asked May 10 '18 02:05

Danny Bravo


People also ask

How to get unique values out of an array in Swift?

Removing duplicates to get unique values out of an array can be a common task to perform. Languages like Ruby have built-in methods like uniq but in Swift, we have to create such methods on our own. The standard library does not provide an easy method to do this.

How do I find duplicates in Swift?

To find duplicates, you could build cross reference by phone number, then filter that down to duplicates only. For example, consider: In Swift 4, you can build the cross reference dictionary with: Or, in Swift 5.2 (thanks to SE-0249 ), you can do:

How to avoid duplicates in an array in Java?

For example, if input array is {1, 2, 1} and r is 2, then the program prints {1, 2} and {2, 1} as two different combinations. We can avoid duplicates by adding following two additional things to above code. See this for an implementation that handles duplicates.

How to generate all possible combinations of elements in array?

Given an array of size n, generate and print all possible combinations of r elements in array. For example, if input array is {1, 2, 3, 4} and r is 2, then output should be {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4} and {3, 4}. Following are two methods to do this. We create a temporary array ‘data []’ which stores all outputs one by one.


2 Answers

You can use flatMap also to combine them in one line.

extension Array {
    var combinationsWithoutRepetition: [[Element]] {
        guard !isEmpty else { return [[]] }
        return Array(self[1...]).combinationsWithoutRepetition.flatMap { [$0, [self[0]] + $0] }
    }
}
    
print([1,2,3,4].combinationsWithoutRepetition)
like image 150
Abdelahad Darwish Avatar answered Sep 27 '22 22:09

Abdelahad Darwish


extension Array {
    var combinations: [[Element]] {
        if count == 0 {
            return [self]
        }
        else {
            let tail = Array(self[1..<endIndex])
            let head = self[0]

            let first = tail.combinations
            let rest = first.map { $0 + [head] }

            return first + rest
        }
    }
}

print([1, 2, 3, 4].combinations)
like image 33
Nader Avatar answered Sep 27 '22 21:09

Nader