Stuart Breckenridge

Extending Array to Enforce Unique Elements

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
        if unique

What we are doing here is extending Array with new functionality in situations where the Elements stored in the array conform to the Equatable2 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, ↩︎

  2. Equatable Protocol Reference, ↩︎

— Supported by —

The Cost of Attending WWDC

Inspired by Casey Liss’ writeup on how much it would cost to attend WWDC, I thought I’d price up a hypothetical trip from Singapore (prices in USD):

  • Flights: $1,484 (United Airlines—Economy) or $5,230 (United Airlines—Business)
  • Hotel: $2,906 (Parc 55, 6 nights)
  • WWDC ticket: $1,599

Total: $5,989 up to $9,735

Gulp. As I said in my previous post, I’ll be streaming the sessions.

Apple TV and the Importance of The

Siri on the new Apple TV is excellent. It saves time and lets you bypass a lot of navigation. However, I find it can be a bit picky about certain requests.

For example, I’m currently re-watching The West Wing. Instead of navigating through the TV series UI, I’ll say something like this:

"Show me West Wing series five."

Apple TV will respond with on screen text telling me it can’t find such a show. So I’ll repeat myself to Siri:

"Show me The West Wing series five."

…and this time Apple TV works fine. Because I included “the” in my request.

It’s a minor frustration that Siri is this sensitive to a missed word.

Upcoming Requirements for watchOS 2 Apps

From Apple’s Developer Website:

Starting June 1, 2016, all new watchOS apps submitted to the App Store must be native apps built with the watchOS 2 SDK or later.

In use, I honestly can’t tell the difference between an app built with watchOS 1 (WatchKit) vs watchOS 2: the performance is sluggish across all third-party apps on my Apple Watch.

Amazon Now Requires Prime Membership for Top Video Games

Tom Phillips at Eurogamer:

You now need a Prime subscription to buy games such as Grand Theft Auto 5, Rainbow Six: Siege or FIFA 16 direct from retail giant Amazon.

The bizarre change, spotted by Videogamer, appears to have quietly taken affect overnight.

But there’s a big caveat to the above. All of these games are still available to buy via Amazon through third-party sellers, whether you have Prime or not.

Despite being able to buy from third-party sellers, this is a disgraceful sales tactic to get people to subscribe to Prime, which is a shame because it’s generally fantastic value.