Generate a Swift array of nonrepeating random numbers

后端 未结 3 1908
猫巷女王i
猫巷女王i 2021-01-20 01:47

I\'d like to generate multiple different random numbers in Swift. Here is the procedure.

  1. Set up an empty array
  2. Generate a random number
  3. Ch

相关标签:
3条回答
  • 2021-01-20 02:28

    If you use your method the problem is, that you will create a new random-number each time. So you possibly could have the same random-number 4 times and so your array will only have one element.

    So, if you just want to have an array of numbers from within a specific range of numbers (for example 0-100), in a random order, you can first fill an array with numbers in 'normal' order. For example with for loop etc:

    var min = 1
    var max = 5
    for var i = min; i<= max; i++ {
        temp.append(i)
    }
    

    After that, you can use a shuffle method to shuffle all elements of the array with the shuffle method from this answer:

    func shuffle<C: MutableCollectionType where C.Index == Int>(var list: C) -> C {
        let count = countElements(list)
        for i in 0..<(count - 1) {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            swap(&list[i], &list[j])
        }
        return list
    }
    

    Ater that you can do something like that:

    shuffle(temp)        // e.g., [3, 1, 2, 4, 5]
    
    0 讨论(0)
  • 2021-01-20 02:35

    Below is my suggestion. I like this way since it is short and simple :)

    let totalCount: Int = 150 //Any number you asssign
    var randomNumArray: [Int] = []
    var i = 0
    while randomNumArray.count < totalCount {
        i++
        let rand = Int(arc4random_uniform(UInt32(totalCount)))
        for(var ii = 0; ii < totalCount; ii++){
            if randomNumArray.contains(rand){
                print("do nothing")
            } else {
                randomNumArray.append(rand)
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-20 02:36

    The construct you’re looking for with your approach might be something like:

    var temp: [Int] = []
    while temp.count < 4 {
        var randomNumber: Int
        do {
            randomNumber = randomInt(1, 5)
        } while contains(temp, randomNumber)
        temp.append(randomNumber)
    }
    

    This will be fine for tiny ranges like yours, but for larger ranges it will be very slow, because for the last few numbers you are waiting for the random number to hit precisely the remaining handful of possibilities. I just tried generating from a range of 200 in a playground and it took 9 seconds.

    If you want a random selection of numbers with guaranteed coverage over a range, you could generate it like by taking that range and shuffling it, like this:

    func shuffle<S: SequenceType>(source: S) -> [S.Generator.Element] {
        var rangen = GeneratorOf { arc4random() }
        let a = Array(Zip2(rangen, source))
        return a.sorted { $0.0 < $1.0 }.map { $0.1 }
    }
    
    let min = 1, max = 5
    shuffle(min...max)
    

    If you want a selection of n non-repeating random numbers from a range 0..<m, there’s a particularly pretty algorithm to do this that generates an ascending sequence of random numbers from that range:

    func randomGeneratorOf(#n: Int, #from: Int) -> GeneratorOf<Int> {
    
        var select = UInt32(n)
        var remaining = UInt32(from)
        var i = 0
    
        return GeneratorOf {
            while i < from {
                if arc4random_uniform(remaining) < select {
                    --select
                    --remaining
                    return i++
                }
                else {
                    --remaining
                    ++i
                }
            }
            return nil
        }
    }
    

    Which you could use like so:

    let engines = [
        "Duck","Emily","Gordon","Henry", "Mavis",
        "Belle","James","Edward","Thomas","Toby"
    ]
    
    let picks = Array(randomGeneratorOf(n: 3, from: engines.count))
    
    for engine in PermutationGenerator(elements: engines, indices: picks) {
        println(engine)
    }
    
    0 讨论(0)
提交回复
热议问题