At some point in your life there comes a time where you will be needing randomness.
But why randomness?
Randomness or a random number has many uses, this includes:
- picking a lottery winner from a list
- generating a unique id/session for a user
- adding an element of unpredictability in games (e.g. loot drops, gacha draws, etc.)
- and many more!
Now, Let us tackle the exciting world of random numbers in Swift!
Dealing with randomness regardless of Swift version
There are many ways to generate number numbers in Swift.
First, we tackle very basics that can be used on any swift version.
There are three typical functions for random numbers, namely:
arc4random() returns a random number between zero and (2^32 or UInt32.max) – 1
arc4random_uniform(n) returns a random number between zero and the (parameter minus one).
drand48() returns a random Double between 0.0 and 1.0
Note: Both arc4random() and arc4random_uniform() use the type UInt32 instead of the more typical Int. Thus, there is a need for conversion for ease of use.
Important!: numbers from these functions are generated with a mathematical formula. Although they appear random, if you repeat the function often enough you will begin to see patterns and repetitions. Thus, it is not recommended for cryptography or security purposes.
arc4random()
– although useful it is known to suffer from a condition called “modulo bias”. Where a particular set of numbers often appear more than others. Thus, it undermines the “randomness” of the function.
let number = arc4random() print("The computer selected: \(number)") //output: The computer selected: 1580707251
arc4random_uniform(n)
– requires one parameter, the upper_bound. It returns a random number between 0 and upper_bound minus 1.
let number = arc4random_uniform(100) print("The computer selected: \(number)") //output: The computer selected: 17
the resulting number will be of type UInt32 so if you want to manipulate the number with other Int numbers in your code then you need to typecast it
let number = Int(arc4random_uniform(20))
drand48()
– will generate a type double number with a value that is between 0.0 to 1.0.
let double_number = drand48() print("The computer selected: \(double_number)") //output: The computer selected: 0.582411752804263
Dealing with randomness from Swift 4.2 and above
Working with random numbers has changed since Swift 4.2 because you can now use native functions!
.random(in: [lower_bound] [range_operator] [upper_bound])
Here is a quick example:
let number = Int.random(in: 0 ..< 100) print("Number: \(number)") //returns a random number from 0 - 99
The example above generates a random integer number between 0 and 100.
Notice that the function has a range operator, namely (..<).
This operator is called the half open range operator where the result will not include the upper bound (thus, 0 – 99)
if however you want to result to include 100, namely a range of numbers from 0 – 100 then you will need to use the closed range operator (…)
let number = Int.random(in: 0 ... 100) print("Number: \(number)") //returns a random number from 0 - 100
The .random(in:) function can be used on several primitive data types such as Int, Double, Float, and even Bool.
Let decimal = Float.random(in: 0 ..< 1) print("Decimal: \(decimal)") //returns a random decimal number from 0.0 - 0.99999
We can also easily randomize boolean now. No need for the usual random number from 0 – 1!
let TrueOrFalse = Bool.random() print("Bool: \(TrueOrFalse)") //returns a random boolean value True/False
There is also a way to easily get a random element in a Collection (array, dictionary) data type via the .randomElement() function
let fruits = ["Banana", "Mango", "Apple", "Orange"] let randomFruit = fruits.randomElement() print("The computer selected: \(randomFruit)") //output: The computer selected Optional("Mango")
Notice that the result was of type optional, so in order to use the value properly we must unwrap it. Since we know that our optional will not fail we can just simply force unwrap (!) the result
let fruits = ["Banana", "Mango", "Apple", "Orange"] let randomFruit = fruits.randomElement()! print("The computer selected: \(randomFruit)") //output: The computer selected Mango