JoeShmoe JoeShmoe - 6 months ago 25
Swift Question

Trying to pass an array to function in swift

I have created the following function to run through the "iN" array and the "nS" array 10 times to combine both arrays into 1. My plan was to push the array to "callUpArrayResults" function with this line "callUpArrayResults(questionsArray)" but I receive a "Cannot convert value of type '[AnyObject]' to expected argument type '[String]'".
As well as a "Cannot assign to property: 'self' is immutable" for this line "callUpArrayResults = arr" am I going about this wrong? Or can I call up the created array result directly from the function if so How would I go about that? I'm new to swift but I am trying to learn any guidance would be appreciated.

func creatArray () {

var iN: [AnyObject] = [
//a
"Xxxxxxxx xxxxxxxxxx1",
"Xxxxxxxx xxxxxxxxxx2",
"Xxxxxxxx xxxxxxxxxx3",
"Xxxxxxxx xxxxxxxxxx4",
"Xxxxxxxx xxxxxxxxxx5",
"Xxxxxxxx xxxxxxxxxx6",
"Xxxxxxxx xxxxxxxxxx7",
"Xxxxxxxx xxxxxxxxxx8",
"Xxxxxxxx xxxxxxxxxx9",
"Xxxxxxxx xxxxxxxxxx10",
"Xxxxxxxx xxxxxxxxxx11",
"Xxxxxxxx xxxxxxxxxx12",
"Xxxxxxxx xxxxxxxxxx13",
"Xxxxxxxx xxxxxxxxxx14",
"Xxxxxxxx xxxxxxxxxx15",
"Xxxxxxxx xxxxxxxxxx16"]

var nS:[AnyObject] = [
"Yyyyyyyyyyyyyy yyyyyyyyy1",
"Yyyyyyyyyyyyyy yyyyyyyyy2",
"Yyyyyyyyyyyyyy yyyyyyyyy3",
"Yyyyyyyyyyyyyy yyyyyyyyy4",
"Yyyyyyyyyyyyyy yyyyyyyyy5",
"Yyyyyyyyyyyyyy yyyyyyyyy6",
"Yyyyyyyyyyyyyy yyyyyyyyy7",
"Yyyyyyyyyyyyyy yyyyyyyyy8",
"Yyyyyyyyyyyyyy yyyyyyyyy9",
"Yyyyyyyyyyyyyy yyyyyyyyy10",
"Yyyyyyyyyyyyyy yyyyyyyyy11",
"Yyyyyyyyyyyyyy yyyyyyyyy12",
"Yyyyyyyyyyyyyy yyyyyyyyy13",
"Yyyyyyyyyyyyyy yyyyyyyyy14",
"Yyyyyyyyyyyyyy yyyyyyyyy15",
"Yyyyyyyyyyyyyy yyyyyyyyy16"]

var questionsArray: [AnyObject] = [AnyObject]()

for var i = 0; i < 10; i++ {

let arrayCount = iN.count
let random = Int(arc4random_uniform(UInt32(arrayCount)))
let xx = iN[random]
let yy = nS[random]
let QnA: [NSObject : AnyObject] = [
"x" : xx,
"y" : yy
]
//remove from array
iN.removeAtIndex(random)
Ns.removeAtIndex(random)
//add dictionary for each question into array
questionsArray.append (QnA)

print(questionsArray)

}
callUpArrayResults(questionsArray)
}

creatArray()

fun callUpArrayResults(arr:[String]){

callUpArrayResults = arr

}

Answer

Every language has a natural way code wants to be written. As part of the process for learning a language, try to learn how code should be written in that language.

In this example, you want to combine the elements of two arrays into an array of dictionaries, randomly select 10 of those dictionaries. In Swift, zip(), map() and prefix() cover everything except the randomization. You need something like a shuffle method for the array.

Here is one that does the Fisher-Yates (fast and uniform) shuffle:

extension CollectionType {
    func shuffle() -> [Generator.Element] {
        var result = Array(self)

        if result.count > 1 {
            for i in 0 ..< result.count - 1 {
                let j = Int(arc4random_uniform(UInt32(result.count - i))) + i
                if i != j {
                    swap(&result[i], &result[j])
                }
            }
        }

        return result
    }
}

With shuffle() in hand, I can solve the problem.

let allQuestions = zip(iN, nS).map {xx, yy in ["x": xx, "y": yy]}
let shuffledQuestions = allQuestions.shuffle()
let first10ShuffledQuestions = shuffledQuestions.prefix(10)

let questionsArray: [AnyObject] = Array(first10ShuffledQuestions)

The first part, zip(iN, nS).map {xx, yy in ["x": xx, "y": yy]} creates an array of dictionaries using the key "x" for iN and "y" for nS. The next part, shuffle() returns an array of dictionaries in a random order. The last part, prefix(10) returns an array slice of the shuffled array containing the first 10 elements. Because prefix() returns an array slice and not an array, use Array() to create an array from the array slice for the final assignment to questionsArray.

This can all be done in one line.

let questionsArray: [AnyObject] = Array(zip(iN, nS).map {xx, yy in ["x": xx, "y": yy]}.shuffle().prefix(10))
Comments