Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Generate Random Int Array include 4 elements and each element among 1...9 and different each other in Swift

Hello Everyone
I am totally beginner and I always trying something. Actually I have solution to myself. But I want to learn best practice and approach.

My Question: I want to create an Array include 4 elements that elements between 1...9 and all elements different each other like this [1, 3, 6, 2] or [4, 3, 9, 2].

So here is the my solution It works but I repeated myself in code. And my code is so rigit just serve one mission. So I will wait your help and advice. By the way sorry for my english grammar

Thank You

/***********************
 GENERATE A RANDOM ARRAY INCLUDE ALL DIFFERENT 4 ELEMENT LIKE THIS [1, 4, 6, 7]
 ***********************/

import Foundation

class Numbers {
    var digit: Int = 4

    /// Creating Array: [Int] all elements different each other and include only 4 element.
    func createNumber() -> [Int] {
        var createdNumber: [Int] = []
        var i = 2

        createdNumber.insert(generate(), at: 0)
        createdNumber.insert(generate(), at: 1)

        while i <= digit {
            if i == 2 && createdNumber[0] == createdNumber[1] {
                createdNumber.remove(at: i - 1)
                createdNumber.insert(generate(), at: i - 1)
            } else if (i == 3 && createdNumber[i - 1] == createdNumber[i - 2]) || (i == 3 && createdNumber[i - 1] == createdNumber[i - 3]) {
                createdNumber.remove(at: i - 1)
                createdNumber.insert(generate(), at: i - 1)
            } else if (i == 4 && createdNumber[i - 1] == createdNumber [i - 2]) || (i == 4 && createdNumber[i - 1] == createdNumber[i - 3]) || (i == 4 && createdNumber[i - 1] == createdNumber[i - 4]) {
                createdNumber.remove(at: i - 1)
                createdNumber.insert(generate(), at: i - 1)
            } else if (i == 4) {
                i += 1
            } else {
                createdNumber.insert(generate(), at: i)
                i += 1
            }
        }
        return createdNumber
    }

    // Helper Method: Generate Random 1...9 1-digit number.
    func generate() -> Int {
        let generatedNumber = Int(arc4random_uniform(9) + 1)
        return generatedNumber
    }
}

1 Answer

Magnus Hållberg
Magnus Hållberg
17,232 Points

If you want to create an array with random INTs that doesn’t respite an easy approach is to generate an array for the range you want the random numbers to be generated from (like 1 to 10) and then simply “take” random indexes from that array (that you then delete) and insert the value into a new empty array. That way you will always have a random unique INT. Even if the random generator “draws” the same index number twice the value for that index won’t repeat since it’s been removed from the range. See example below. Not sure if this is the best way to do this but it has worked for me and its very simple and easy to scale.

func randomSequenceGenerator(min: Int, max: Int) -> () -> Int {
    var numbers = [Int]()
    return {
        if numbers.count == 0 {
            numbers = Array(min ... max)
        }

        let index = Int(arc4random_uniform(UInt32(numbers.count)))
        return numbers.remove(at: index)
    }
}

let getRandom = randomSequenceGenerator(min: 0, max: 9)
var randArray = [Int]()

for _ in 0...3 {
    randArray.append(getRandom())
}
Caleb Kleveter
Caleb Kleveter
Treehouse Moderator 37,862 Points

Magnus Hållberg, I just wanted to let you know I changed your comment to an answer. Because this is an answer to the question, we want to keep the thread organized and easy to read. This also allows your answer to be upvoted and/or accepted.