Benjamin
Benjamin

Reputation: 655

Swift 3.0 - How to iterate through a 2D array and append "value" to another array

I'm very new to Swift and have never coded Objective-C.

I'm am trying to Iterate through a 2D array quiz (of questions/answers ) and add the answers to another array onlyAnswers I have tried using a for loop within a for loop but run into problems, I'm obviously missing something...

why can't I use quiz[j][1] within the while loop to append to the new array? onlyAnswers.append(quiz[j][1] or even as a value to do simple math let math = 1 + quiz[j][1] ?

var quiz = [
    //Array of questions with their answers. question/answers
    ["2 + 1 ", 3],
    ["10 - 8", 2],
    ["4 x 2", 8],
    ["10 / 2", 5],
    ["7 + 2", 9]
]
var onlyAnswers: [Int] = []


var j = 0
while j < quiz.count{
    // print answers
    print(quiz[j][1]) // 3, 2, 8, 5, 9

    // do something with quiz[j][1]

    onlyAnswers.append(quiz[j][1])
     // Error: Cannot convert value of type 'NSObject' tp expected argument type 'Int'

    j += 1
}

any code examples of how to actually do this would be great?

Upvotes: 0

Views: 3143

Answers (3)

OOPer
OOPer

Reputation: 47876

Swift is a type safe language, so types of expressions are checked in compile-time.

Your quiz is shown as [Array<Any>] in the Quick Help pane of Xcode, which means the type of quiz[j][0] is Any. You declared your onlyAnswers as [Int], so appended value needs to have type Int.

So, explicitly casting to Int is one way to solve your issue, and another is changing your data structure.

With using tuple type, you can assign appropriate types for each element.

var quiz: [(question: String, answer: Int)] = [
    //Array of questions with their answers. question/answers
    ("2 + 1 ", 3),
    ("10 - 8", 2),
    ("4 x 2", 8),
    ("10 / 2", 5),
    ("7 + 2", 9)
]

(This causes a little bit difficulty in some cases, but that's another issue.)

With this, you can write your while loop as:

var onlyAnswers: [Int] = []

var j = 0
while j < quiz.count{
    // print answers
    print(quiz[j].answer) // 3, 2, 8, 5, 9

    // do something with quiz[j].answer

    onlyAnswers.append(quiz[j].answer)

    j += 1
}

Or shorter:

var onlyAnswers: [Int] = []
for j in 0..<quiz.count {
    // print answers
    print(quiz[j].answer) // 3, 2, 8, 5, 9

    // do something with quiz[j].answer

    onlyAnswers.append(quiz[j].answer)
}

A little more shorter:

var onlyAnswers: [Int] = []
for qa in quiz {
    // print answers
    print(qa.answer) // 3, 2, 8, 5, 9

    // do something with qa.answer

    onlyAnswers.append(qa.answer)
}

Upvotes: 1

Dravidian
Dravidian

Reputation: 9945

struct's and tuples's will be more suitable for this.

var onlyAnswers = [Int]()

var j = 0
while j < quiz.count{

    print(quiz[j][1]) // 3, 2, 8, 5, 9

    if let isInt = quiz[j][1] as? Int{
       onlyAnswers.append(isInt)
    }else{
      print("Value \(quiz[j][1]) isn't of type Int , Thus cant be appended to an array of type [Int] ")
       }

   j += 1
}

Upvotes: 1

Yash Tamakuwala
Yash Tamakuwala

Reputation: 2056

Change that line to

onlyAnswers.append(quiz[j][1] as! Int)

because your quiz array is of mixed type. One element of type string and other of type Int. And onlyAnswers is strictly of type Int. So to append element quiz[j][1], you need to explicitly unwrap it to type Int.

Upvotes: 0

Related Questions