Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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.