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

iOS Swift

I want to create a function which print each element in an array in a ordered way but when it reached the last element i want that this function start again from the beggining printing each element.I want to do this every time that reached the last element.

4 Answers

The idea was when a user click a button in an app which shows information every time a user click to this button i would like to show him all the information without interrupting the app.

In that case, you can just keep an Array of all the information you wanna show, and then just iterate over and display that, because the user only needs information once (and not infinitely over and over again). That would just look something like this:

class ViewController: UIViewController{
    var infoForDisplay = ["Some", "Information", "That", "Will", "Be", "Displayed", "To", "The", "User"]
    @IBAction func displayInfo() -> Void{
        for info in infoForDisplay{
            // The best way to do this is probably with a UITableView or something similar, but I'll simply use print as the display function for now
            print(info)
        }
    }
}
extension SequenceType {
    func infinitePrint() {
        self.forEach { print($0) }
        infinitePrint()
    }
}

infoForDisplay.infinitePrint()

I don't know why we're creating infinite loops though! Would be a good idea to add some sort of condition :)

how can i add the condition to print those element in an array each time the user click a button?

Hey Franklin,

There's a ton of good information in this thread already. If you only want to print the contents of the array a single time then you can do it like this. If you want to do it infinitely, which has already not been suggested, you would use recursion.

@IBAction func buttonPressed(sender: UIButton) {
    infoForDisplay.forEach { print($0) }    
}

If you only want to print the array every time someone clicks the button, you just need the for each loop:

for element in array {
    print(element)
}

You'll have to put that for each loop inside a function connected to the button in question. If you don't know how to connect a button in the User Interface to a method in the View Controller, these videos should help you:

https://teamtreehouse.com/library/build-a-simple-iphone-app-with-swift-20/view-controllers-and-views/creating-iboutlets

https://teamtreehouse.com/library/build-a-simple-iphone-app-with-swift-20/view-controllers-and-views/using-ibaction-to-execute-methods

If you haven't done so already, I'd recommend going through the course these videos come from:

https://teamtreehouse.com/library/build-a-simple-iphone-app-with-swift-20

Try sticking the for loop that prints each element in the array in a while loop.

Please can you make an example?

Alright. But what do you want your stopping condition to be? The way you've described your function, it looks like you want to create a function that runs forever printing the contents of the array, which generally isn't a good practice in computer coding. I've set up the function so that it prints all the elements in the array a certain number of times, but it'd be pretty easy to modify that function so that it prints indefinitely, if that's truly what you want. I wouldn't recommend turning this into a function that goes on forever with no way to stop it, though.

func printForever<Element>(array: Array<Element>) {
    let maxPrints = 20
    var currentPrint = 0
    while (currentPrint < maxPrints) {
        for element in array {
            print("\(element)")
        }
        currentPrint += 1
    }
}

If you're dead set on making a function that prints forever with no way to stop it, you can just get rid of maxPrints, get rid of currentPrint, get rid of the line of code that increments currentPrint, and put true in the parentheses where the condition for the while loop is.

DISCLAIMER: I just quickly wrote all this code in the Treehouse answer sheet, so it may not compile, but if it doesn't, you'll get the idea

This is probably a bad idea, because it sounds like it would cause an infinite loop, which will take up all the resources of the device, and iOS will kill your app. If you really insist on doing this, you could do it in 1 of 2 ways: Recursion or a normal loop.

Recursion is perhaps the easiest to code, as you just write a function to do what you want that calls itself when it wants to restart the process. Eventually, this will cause the app to crash, however, because the app will run out of available memory. If it's just a quick and dirty hack for debugging purposes (which it sounds like it would be), this would probably serve, however. This is how to implement this recursively:

func printArrayInfinitely<Element>(array: Array<Element>) -> Void{
    for object in array{
        print(object)
    }
    printArrayInfinitely(array)
}

You should never ship code like this (from either example) in an actual app, because it will hog all the memory and crash the app, but the loop method will allow it to last the longest. Here's how you implement that:

let array = ["Some", "Array", "With", "Whatever"]
var index = 0
while true{
    print(array[index])
    index += 1
    if index == array.count{
        index = 0
    }
}

These solutions are also valid. But it'd probably be better to use generics for the function.

func printArrayInfinitely<Element>(array: Array<Element>) -> Void{
    for element in array{
        print(element)
    }
    printArrayInfinitely(array)
}

Either will work, but I suppose generics are more Swifty than just just an [AnyObject]. I'll update my answer accordingly. Thanks for the tip!

You're welcome!