问题
I have a text field and a button that generates a random set of characters. Set 1 = lowercase, set 2 = uppercase, set 3 = numbers, set 4 = symbols
I want the the button to generate no more no less that 10 characters and minimum pull from each of the sets at least once.
My idea of how to do it so far is
let roomIDGenerated = uniqueRoomID.text
let roomIDCount = roomIDGenerated?.characters.count
let randomCharacterSet = arc4random() upp
while roomIDCount < 10 {
<#code#>
}
But I don't see how to do it...i don't always want the first 4 characters to always be one of each.. maybe one of the required sets is used last.
I'm kinda stuck in general, any help would be appreciated
回答1:
Martin commented with the same approach I was taking. Here is my implementation:
extension CollectionType {
var random: Generator.Element {
guard !isEmpty else { fatalError("array cannot be empty") }
let array = Array(self)
return array[Int(arc4random_uniform(UInt32(array.count)))]
}
}
// from http://stackoverflow.com/a/24029847/1223781
extension MutableCollectionType where Index == Int {
func shuffled() -> Self {
var copy = self
copy.shuffle()
return copy
}
mutating func shuffle() {
guard count >= 2 else { return }
for i in 0..<count - 1 {
let j = Int(arc4random_uniform(UInt32(count - i))) + i
guard i != j else { continue }
swap(&self[i], &self[j])
}
}
}
let sets = ["abc", "ABC", "123", "#$%"].map { Array($0.characters) }
let size = 10
var randoms = sets.map { $0.random }
while randoms.count < 10 {
randoms.append(sets.random.random)
}
print(randoms.shuffled()) // ["b", "b", "3", "c", "#", "%", "A", "#", "1", "%"]
来源:https://stackoverflow.com/questions/36931474/how-to-have-10-characters-total-and-make-sure-at-least-one-character-from-4-diff