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?

- 30,560
- 17
- 97
- 143

- 475
- 4
- 11
-
3What have you tried so far? – G. LC Jul 31 '18 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. – Vladimir Sukanica Jul 31 '18 at 17:33
-
1Possibly Related: https://stackoverflow.com/questions/32773593/generate-array-of-unique-random-numbers-within-inclusive-range – Ahmad F Jul 31 '18 at 20:34
4 Answers
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

- 475
- 4
- 11

- 217
- 1
- 10
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 Int
s, 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 Int
s, 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() }

- 30,560
- 17
- 97
- 143
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 }
}

- 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
-
-
1anyway, 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
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
}

- 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