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
Supratik Majumdar
2,478 PointsUnexpected Error Array Increment
struct FactBook {
let factarray = ["Hello World", "Hello MacOS", "Hello iOS"]
var counter = 0
func ramdomFact () -> String{
return factarray[counter++];
}
}
[code format edited by Mod]
The return statement throw up an error when implemented in a .swift file
5 Answers
Steve Hunter
57,712 PointsHi,
I don't like the structure of your code; there are probably prettier ways of doing this. However, I had a play and came up with the following, which does work:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var elementLabel: UILabel!
var factBook: FactBook = FactBook()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func getNextElement(sender: AnyObject) {
// check if you've gone over the number of elements - this is hard-coded; poor!
// should have a method to return the length of the private array and test against that
if(factBook.counter >= 3){
factBook.counter = 0
}
// call the method that just returns a string
elementLabel.text = factBook.getNextFact()
factBook.counter++
}
}
// FactBook.swift
import Foundation
struct FactBook{
// create an array - should be done on the fly and have access to getter and setter methods too
var factArray = ["Line one", "Line two", "Line three"]
var counter: Int
init(){
// make sure the Int is zeroed
self.counter = 0
}
// the sole functionality - counter testing is done elsewhere
func getNextFact() -> String {
return factArray[counter]
}
}
Steve Hunter
57,712 PointsHi Supratik,
I edited the post to show the post more easily.
What are you trying to acheive here? What's the question?
I can help more from there.
Thanks,
Steve.
Supratik Majumdar
2,478 PointsThe struct defined here is for an simple App. It consists of a label and a button. When the button is pressed it changes the content of the label by calling the randomFact() method. Sample function call from View Controller: label.text = randomFact() The ViewContoller and the struct are in separate swift files.
The error of the return statement: 'Int' is not convertible to '@Ivalue UInt8'
Steve Hunter
57,712 PointsOK - that makes sense. Is this a Treehouse exercise? I'd not expect to see factarray not in Camel Case.
Talk me through your code; let's see why this isn't doing what you expect it to.
First, though, what code are you given as a starter?
Steve.
Supratik Majumdar
2,478 Pointsclass ViewController: UIViewController {
@IBOutlet weak var FunFactLabel: UILabel! //Label I am outputting to
var factBook = FactBook() //struct in another swift file FunFacts.swift
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
FunFactLabel.text = factBook.ramdomFact() //member function call
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func showFunFact() {
FunFactLabel.text = factBook.ramdomFact() //member function call
}
}
There was actually a TreeHouse course based on the same idea but the conditions were slightly different. The course asked me to display a random string form a array of strings in a random manner. The random condition did work fine.
What I want to do is to sequentially go through the array and print the entire contents of the array to the label as I keep pressing the button.
But, view consists of a button and a label
Steve Hunter
57,712 PointsOne reason it will generate an error is that you are incrementing counter but not bounds checking it again the array.
So, the counter can reach a number that is greater than the number of elements in the array which will throw an exception. In my code, I test the value of counter and make sure it doesn't get higher than 2, as the hard-coded array has three elements. It would be better tested as if (counter >= factBook.factArray.count) so that the size of the array is taken into account.
Steve Hunter
57,712 PointsI had a little play with this ... have a look at the following. This starts with an empty array and allows you to add to it. There's a warning to catch the error of trying to access the array when it is empty. (I'm using a deprecated class there, but it still works!)
import UIKit
import Foundation
class ViewController: UIViewController, UIAlertViewDelegate {
@IBOutlet weak var elementLabel: UILabel!
var factBook: FactBook = FactBook()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// init the struct
//var factBook: FactBook = FactBook()
}
@IBAction func addNewElement(sender: AnyObject) {
factBook.addNewLine()
}
@IBAction func getNextElement(sender: AnyObject) {
if(factBook.factArray.count == 0) {
var anAlert: UIAlertView = UIAlertView(title: "Empty array", message: "There are no elements to show - add one first", delegate: self, cancelButtonTitle: "OK")
anAlert.show()
return
}
if(factBook.counter >= factBook.factArray.count){
factBook.counter = 0
}
elementLabel.text = factBook.getNextFact()
factBook.counter++
}
}
// FactBook swift file
import Foundation
struct FactBook{
var factArray: [String] = []
var counter:Int
init(){
self.counter = 0
}
func getNextFact() -> String {
return factArray[counter]
}
mutating func addNewLine(){
var elements = factArray.count + 1
factArray.append("Line \(elements)")
}
}
Supratik Majumdar
2,478 PointsSupratik Majumdar
2,478 PointsYes Steve, even I had to pay around and got your and another solution (attached below) But, can you give me any reason why does my pervious code does not work:
But here in the above solution the issue becomes that counter is a global variable. Thus, any new instance new of FactBook will not have a independent copy of counter.
Your code structure is much better