-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?

3
  • 3
    What have you tried so far? Commented Jul 31, 2018 at 17:31
  • I have tried to make for loop and to use array.contains(n) but it either doesn’t fill all 30 numbers or it repeats some of them. I am stucked. Commented Jul 31, 2018 at 17:33
  • 1
    Possibly Related: stackoverflow.com/questions/32773593/… Commented Jul 31, 2018 at 20:34

4 Answers 4

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() }
Sign up to request clarification or add additional context in comments.

Comments

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

2 Comments

Thank you, your'e a life saver!
Can you make it the right answer? @VladimirSukanica
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 }
}

3 Comments

Maybe we could start using Swift 4.2, e.g. Int.random(in: 0 ... 10)?
Absolutely, once we have a non-beta version.
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.
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
}

1 Comment

Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.