Reputation: 39
I am trying to create an array that would preferably store the object in this format [[[String, CGPoint, Bool]]]
, but I get errors all over the place so I decided to set it as [[[AnyObject]]]
.
Here is my code for declaring the array:
var savePlayerState:[[[AnyObject]]] = []
As you can see it's a multidimensional array, which I need to store 3 things: the current time, the player's location, and a simple Bool. Here is how I am trying to save the data to the array:
savePlayerState.append([timeLabel.text, player.position, isPlayerAlive])
My error is this:
Type of expression is ambiguous without more context
I really am not sure what's going on, I have tried casting several different ways but I am stuck. I also do need to save all of these variables in an array, which I will be appending to every game loop and saving in a log for testing. How can I accomplish this? I feel like the solution is simple, I'm just missing it.
Upvotes: 2
Views: 913
Reputation: 154711
Usually using AnyObject
in Swift is the wrong approach unless it is required for interfacing to Cocoa/Cocoa touch. You should probably use a custom structure to store PlayerState
and then create an array of those:
struct PlayerState {
var time: String
var position: CGPoint
var isAlive: Bool
}
var savePlayerState:[PlayerState] = []
savePlayerState.append(PlayerState(time: "10:05", position: CGPointMake(2.3, 2.4), isAlive: true))
savePlayerState.append(PlayerState(time: timeLabel.text, position: player.position, isAlive: isPlayerAlive))
You can implement the CustomStringConvertible
protocol for your structure to make printing your log easier:
struct PlayerState: CustomStringConvertible {
var time: String
var position: CGPoint
var isAlive: Bool
var description: String { return "time: \(time), position: (\(position.x), \(position.y)), isAlive: \(isAlive)" }
}
savePlayerState.append(PlayerState(time: "10:05", position: CGPointMake(2.3, 2.4), isAlive: true))
savePlayerState.append(PlayerState(time: "11:03", position: CGPointMake(1.0, 1.0), isAlive: false))
for state in savePlayerState {
print(state)
}
Output:
time: 10:05, position: (2.3, 2.4), isAlive: true time: 11:03, position: (1.0, 1.0), isAlive: false
Upvotes: 2
Reputation: 8411
I don't think you actually want/need a multi-dimensional array. If you do absolutely need it to be a nested collection, please explain why.
The code below illustrates how your array works. (I made it an array of Int
for simplicity)
var savePlayerState:[[[Int]]] = [[[1],[2]],[[3],[4]]] // this a triple nested array
var firstNest = savePlayerState.first // [[1], [2]]
var secondNest = firstNest!.first // [1]
var thirdNest = secondNest!.first // 1
You can't append an Int
to savePlayerState
because it expects an element of type [[Int]]
. One dimension less than itself.
In your code :
savePlayerState.append([timeLabel.text, player.position, isPlayerAlive])
You are appending a 1 dimensional array to a 3 dimensional array. Which does not work because it expects a 2 dimensional array. You are also not appending one object with three values, but three different values with different types.
Retrieving one specific value will be a nightmare.
This will work :
savePlayerState.append([[("someText", CGPointZero, true)]])
But it will still not be very useful.
Notice the ()
around the values. This will make the values into a tuple
. Then you already at least have one element for each collection of values.
What you do want is an element that holds the three values. This can be a custom struct
or class
, but it can also be a tuple
.
When working with tuples
it is convenient to create a typealias
// this is a typealias to give the tuple a name
typealias aStringAPointandABool = (string:String,point:CGPoint,bool:Bool)
var tupleArray : [aStringAPointandABool] = []
var myTyple = (string:"SomeString",point:CGPointZero,bool:true)
tupleArray.append(myTyple)
// this is a struct with variables for the different values
struct myContainer {
var string : String = ""
var point : CGPoint = CGPointZero
var bool : Bool = true
}
var myStructArray : [myContainer] = []
var myStruct = myContainer(string: "SomeString", point: CGPointZero, bool: true)
myStructArray.append(myStruct)
Upvotes: 2