I recently started learning swift via an online course.
I was given the Task to generate a passwort out of a given Array containing characters. We learned mainly two code examples to randomly choose one.
variable[Int.random(in: 0...25)]
variable.randomElement()
Both work just fine when pulling out one single element out of an array but only "variable[Int.random(in: 0...25)
" when combined multiple times with a plus (+).
Why is that?
I looked up the documentation but couldn't find an answer
https://developer.apple.com/documentation/swift/array/2994747-randomelement
Explanation:
This code works:
let alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
//The number of letters in alphabet equals 26
var password = alphabet[Int.random(in: 0...25)] + alphabet[Int.random(in: 0...25)] + alphabet[Int.random(in: 0...25)] + alphabet[Int.random(in: 0...25)] + alphabet[Int.random(in: 0...25)] + alphabet[Int.random(in: 0...25)]
print(password)
This code does not work, because "randomElement()" gets grey after combining multiple with plus (why?)
let alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
//The number of letters in alphabet equals 26
var password = alphabet.randomElement() + alphabet.randomElement() + alphabet.randomElement() + alphabet.randomElement() + alphabet.randomElement() + alphabet.randomElement()
print(password)
Edit: Thanks for the fast explanation guys !
The difference is that randomElement
returns an optional string ( String?
), as opposed to the subscript that returns a non-optional. Why does randomElement
return an optional string? Well, what if the array is empty?
And Swift can't figure out how to add 2 optional strings (let alone 6! So it just gives up). One way to fix this is to force-unwrap the return values of randomElement
:
let password = alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()!
We know the array is not empty, so we can safely force-unwrap here.
Arguably, randomElement
is the better method to use here, because it forces you to think about the situation where the array is empty, and handle it accordingly. The first approach with subscripts doesn't have checks for whether the array is empty, or whether the indices are correct, etc.
This is because of the different return type between the two approaches.
Indexing an array of strings return, as you would expect, the String at that index.
However the .randomElement()
function has a different signature: it return an optional element of the sequence, in your case an optional string (String?).
The '+' operator is defined for strings, but not for optional Strings. To add together the elements returned from .randomElement()
you would need to unwrap them first. Given you have a closed sequence you it would be safe to force unwrap them with '!':
var password = alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()! + alphabet.randomElement()!
Instead of writing many times the same code, try some loops:
let alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
var i = 0
var temp = ""
//The number of letters in alphabet equals 26
while i < 6 {
temp = temp + alphabet[Int.random(in: 0...25)]
i += 1
}
let password = temp
print(password)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With