-1

I want to use arc4random to generate array of 30 different numbers, so that there is no repeating in it. How can I do it?

Ahmad F
  • 30,560
  • 17
  • 97
  • 143

4 Answers4

2

It may be a pretty heavy action but you can do like that:

   var randomNumbers: [Int] = []
   while randomNumbers.count != 30{

       let number = Int(arc4random_uniform(1000) + 1)
       if randomNumbers.contains(number) {
          print("Already Exits")
       }else{
          randomNumbers.append(number)
       }
   }

replace "1000" for a range of number that you need. That function generated 30 different number between 0...1000

Victor Lucas
  • 217
  • 1
  • 10
2

Update:

Thanks to @Sulthan for his elegant thought (commented on Gereon's answer):

anyway, depending on the difference between limit and the number of generated elements this can have a terrible performance. The problem is the case when limit is close to the number of generated elements. Then it would be much better to take 1..<limit and shuffle it.

Which means that there is no even need to generate random Int. The simplest way I could think of is to do it as (Swift 4.2):

let randoms = Array(0..<30).shuffled()

therefore randoms is an array of Ints, contains 30 unique values from 0 to 29.

Less Than Swift 4.2:

However, if you are not using Swift 4.2, I would recommend to check this great answer for getting shuffled collection.




Ignored Solution:

You could achieve it like this:

var uniques = Set<UInt32>()

func generateUniqueUInt32() -> UInt32 {
    let random = arc4random_uniform(31)

    if !uniques.contains(random) {
        uniques.insert(random)
        return random
    } else {
        return generateUniqueUInt32()
    }
}


let randomArray = Array(0..<30).map { _ in Int(generateUniqueUInt32()) }

Therefore randomArray is an array of Ints, contains 30 unique values from 0 to 29.

Swift 4.2:

You should replace:

let random = arc4random_uniform(31)

with:

let random = Int.random(in: 1..<30)

which means that generateUniqueUInt32 should return -directly- Int (and renamed to generateUniqueInt):

func generateUniqueInt() -> Int {
    let random = Int.random(in: 1..<30)

    if !uniques.contains(random) {
        uniques.insert(random)
        return random
    } else {
        return generateUniqueInt()
    }
}

let randomArray = Array(0..<30).map { _ in generateUniqueInt() }
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
0

Use a Set to store the generated numbers so far

func thirtyUniqueRandomNumbers(_ limit: Int) -> [Int] {
    var randoms = Set<Int>()
    repeat {
        let rnd = Int(arc4random_uniform(UInt32(limit)))
        if !randoms.contains(rnd) {
            randoms.insert(rnd)
        }
    } while randoms.count < 30
    return randoms.map { $0 }
}
Gereon
  • 17,258
  • 4
  • 42
  • 73
  • Maybe we could start using Swift 4.2, e.g. `Int.random(in: 0 ... 10)`? – Sulthan Jul 31 '18 at 18:03
  • Absolutely, once we have a non-beta version. – Gereon Jul 31 '18 at 18:06
  • 1
    anyway, depending on the difference between `limit` and the number of generated elements this can have a terrible performance. The problem is the case when `limit` is close to the number of generated elements. Then it would be much better to take `1.. – Sulthan Jul 31 '18 at 18:14
0

Here is a simple solution. Start a while loop. Within this loop generate a random number (between 0 and 1000). And then append the number into your array if the array doesn't contains the number.

func generateArrayOfRandomNumbers() -> [Int] {
    var array: [Int] = []
    while array.count < 30 {
        let randomInt = Int.random(in: 0...1000)
        guard !array.contains(randomInt) else { continue }
        array.append(randomInt)
    }
    return array
}
nslllava
  • 589
  • 2
  • 9
  • 19
  • Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation would greatly improve its long-term value](//meta.stackexchange.com/q/114762/206345) by showing _why_ this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Blue Aug 01 '18 at 02:05