Home > Back-end >  How to get random element from CharacterSet in Swift
How to get random element from CharacterSet in Swift

Time:10-21

I have an array of characters the user has already entered. I would like to get a random character that the user has not already entered from a combined list of all of the alphanumeric characters, the punctuation characters and the symbols. I have looked through the documentation but can't find a way to get a random element from a CharacterSet, which seems odd... I feel like I am missing something obvious.

func newRandomCharacter() -> Character {

let validCharacters: CharacterSet = .alphanumerics.union(.punctuationCharacters).union(.symbols)

var setOfUsedCharacters = CharacterSet()
// usedCharacters: [Character]
usedCharacters.forEach { setOfUsedCharacters.insert(charactersIn: String($0)) }

let setOfUnusedCharacters = validCharacters.subtracting(setOfUsedCharacters)

return setOfUnusedCharacters.randomElement() <- ???

}

CodePudding user response:

Well, I guess is what you are missing is, questioning, what I wanna do and how to solve it:

I want to get a random characters out of a collection of characters.

Or:

I want to get a random index in the range of [0..X], where X must be the total number of character items in your "setOfUnusedCharacters" collection.

Ending up:

Calculate a random integer value that is in beetween zero and the total amount of characters

CodePudding user response:

A CharacterSet is not a Collection. It is a SetAlgebra.

It is not, despite its name, "a Set of Characters." It is a "set" of UnicodeScalars (not Characters) in the mathematical sense: a list of rules that define whether a given UnicodeScalar is contained. There is no direct way to enumerate the values. There are inefficient ways to generate a complete list since UnicodeScalar is over a finite range, but it's quite massive.

I'm curious how you would use this, though. This may include a lot of characters you're not expecting like UNDERTIE (‿), SAMARITAN PUNCTUATION BAU (࠳), and THAI CHARACTER FONGMAN (๏). Are you really looking to pick a random value out all Unicode alphanumerics and punctuation? (There are over 800 punctuation characters, for example, and by my rough count maybe 25k alphanumerics. I haven't counted symbols yet. The chance that you'll get a character on a US keyboard is pretty close to zero.)

I expect this is the code you're really looking for:

let asciiRange = 33...126
let randomCharacter = asciiRange.randomElement()
    .flatMap(UnicodeScalar.init)
    .flatMap(Character.init)!

This will return a random, printable ASCII character.

  • Related