On the subject of our inability to pick random numbers, Keith Hillman writes1:

You might think that you know how to choose a random number but in all likelihood you are probably falling for a number of common mistakes that are giving the game away.

Software can solve this issue. I’m going to write a function that generates six random numbers for my next lottery ticket and will then store those numbers in an `Array`. The problem is that I can’t stop the random number function from generating duplicates and, out of the box, an `Array` will not stop duplicate values from being appended. Let’s have a look at how to enforce uniqueness in an `Array`.

First, let’s see what the basic code looks like before the problem is solved.

``````var numbers = [Int]()

while numbers.count < 6 {
numbers.append((Int(rand() % 49)) + 1)
}
``````

If you run this a few times you’ll begin to see duplicates appear in the numbers array.

```[29, 1, 15, 12, 15, 17]
```

To stop that from happening you could generate your numbers, add them to a `Set`, check it has a count of six and then add them to an `Array`, or you could iterate over each number in the array and compare it to every other number in the array, or as we’re about to do, you could extend the array to include a new `appendIfUnique` function that can be reused easily.

``````extension Array where Element:Equatable
{
mutating func appendIfUnique(newElement:Element){
var unique:Bool = true
for item in self where newElement == item
{
unique = false
break
}
if unique
{
self.append(newElement)
}
}
}
``````

What we are doing here is extending `Array` with new functionality in situations where the `Element`s stored in the array conform to the `Equatable`2 protocol. Types that conform to `Equatable` can be compared for value equality using `==` and `!=`.

The function is declared as `mutating` because we are modifying the array from within the function. A boolean—`unique`—is used to track the result from the equality test. Looping through the array with the `for` statement, the `unique` boolean will be changed to `false` when the element to be added has the same value as the the element being checked, at which point the `for` loop will `break`. Finally, if `unique` remains `true` at the end of the `for` loop, the newElement is added to the array.

In use, the revised code is almost identical:

``````var numbers = [Int]()

while numbers.count < 6 {
numbers.appendIfUnique((Int(rand() % 49)) + 1)
}
``````

You can try this code using the IBM Swift Sandbox.

1. Why We Can’t Choose Random Numbers, http://www.psychology24.org

2. Equatable Protocol Reference, developer.apple.com