0

Why isn't this working?

The error where I'm trying to assign the value of the dictionary to false is where it's failing. It returns this error "fatal error: Array index out of range" as shown in the output at the bottom.

var tupleCount = 0
for var i = 0; i < width; ++i {
    for var j = 0; j < height; ++j {

        arrayOfTupleClass.append(TupleClass(newX: i, newY: j, newXMax: width, newYMax: height))

        print("arrayOfTupleClass.count: \(arrayOfTupleClass.count)")
        print("arrayOfTupleClass[tupleCount]: \(arrayOfTupleClass[tupleCount])")
        print("tupleCount: \(tupleCount)")
        print("imageNum: \(imageNum)")

        // placing '0' in place of dictionary Array index for simplicity
        pointDictionaryArray[0][arrayOfTupleClass[tupleCount]] = false // <-- error here

        tupleCount++
    }
}

This is how my array of dictionaries is set up:

var arrayOfTupleClass = [TupleClass]()
var pointDictionaryArray = [[TupleClass: Bool]]()

this is my TupleClass which should cover for having a class as a key for a dictionary, because I made it hashable.

class TupleClass: Hashable {
    var x: Int!
    var y: Int!
    let yMax: Int!
    let xMax: Int!

    var weight: Int = 0

    init(newX: Int, newY: Int, newXMax: Int, newYMax: Int) {
        x = newX
        y = newY
        yMax = newYMax
        xMax = newXMax
    }

    func setWeight(newWeight: Int) {
        weight = newWeight
    }

    func getWeight() -> Int {
        return weight
    }

    // required for the Hashable protocol
    var hashValue: Int {
        return x * yMax + y
    }
};

// required function for the Equatable protocol, which Hashable inheirits from
func ==(left: TupleClass, right: TupleClass) -> Bool {
    return (left.x == right.x) && (left.y == right.y)
}

This is the output:

arrayOfTupleClass.count: 1
arrayOfTupleClass[tupleCount]: My_Project_Name.TupleClass
tupleCount: 0
imageNum: 0
fatal error: Array index out of range
brw59
  • 502
  • 4
  • 19
  • the variable I replaced with a '0' on the error line was the 'imageNum' btw, this isn't the issue, but I feel like someone is going to bring it up, so I'm mentioning it now – brw59 Mar 17 '16 at 04:26
  • You might try .. pointDictionaryArray[0][arrayOfTupleClass[tupleCount]-1] = false. The array count is always 1 higher than the index of the last element of the array. For example, an array of 10 elements are indexed 0-9 so attempting to reference element "10" would throw an error. I was going to post this as an answer, but I'm not as familiar with this language as I am a few others. – LuvnJesus Mar 17 '16 at 04:33
  • @LuvnJesus the "arrayOfTupleClass[tupleCount]" returns a class instance, so I can't subtract a number from it. I tried it anyway and confirmed it doesn't work – brw59 Mar 17 '16 at 04:40

1 Answers1

0

As ar as i know you can't use a swift Class Name as a reference (nor an Obj-C one in newer releases).. However, why now refer to

    let myclassName = self.className
    let anotherClassName = NSClassFromString(self.classForCoder)

I've just slapped together a quick playground example to toy with:

import Foundation

debugPrint("Hello, World, Here we go from the PLayground template!")

let width = 100 // from your code
let height = 100 // from yoru code

typealias theTup = (newX: CGFloat, newY: CGFloat, newXMax: CGFloat,     newYMax: CGFloat) // setting a typ alias to your tuple format


var theTupArray: [theTup] /*Strong typing*/  = [theTup]() // lets make a new array (with default zero element value)

// lets add some default values for testing, nothing special
theTupArray.appendContentsOf([
    (newX: 1.0, newY: 2.0, newXMax: 2.0, newYMax: 5.0),
    (newX: 2.0, newY: 3.0, newXMax: 4.0, newYMax: 10.0),
    (newX: 3.0, newY: 4.0, newXMax: 6.0, newYMax: 15.0),
    ]
)

// now for-each element in the `theTupArray`... See Swift .forEach.. Or other shorthand methods like .map etc...

theTupArray.forEach { (
    newX: CGFloat,
    newY: CGFloat,
    newXMax: CGFloat,
    newYMax: CGFloat) in

    debugPrint("NewX 1:\(newX), NewY: \(newY), NewXMax: \(newXMax), NewYMax: \(newYMax)", terminator: "\n")

}

Hope this quick re-write helps :)

Adrian Sluyters
  • 2,186
  • 1
  • 16
  • 21
  • I know that I can use a class or struct as a reference, I just haven't successfully done so yet: http://stackoverflow.com/questions/31438210/how-to-implement-the-hashable-protocol-in-swift-for-an-int-array-a-custom-strin – brw59 Mar 17 '16 at 04:43
  • Just a shot, have you tried: `pointDictionaryArray[0].valueForKey`? Or either way referencing dictionaries too by using "valueForKey" for the Obj-C side of things? – Adrian Sluyters Mar 17 '16 at 04:47
  • Just to add, doesn't work for pre swift "classes" which aren't derived from Obj-C classes... – Adrian Sluyters Mar 17 '16 at 04:48
  • @Adrian_Sluyters that was a great idea, it won't compile, here's what I get: " 'inout [[TupleClass: Bool]]' (aka 'inout Array>') is not convertible to 'Array' " I imagine this is my problem ... but I don't know how to fix it. Any more suggestions? – brw59 Mar 17 '16 at 04:58
  • then transforming using .map or .forEach? i.e. Ill post it in my answer – Adrian Sluyters Mar 17 '16 at 05:04
  • @Adrian_Sluyters I see that it's creating an array of tuples, but how do I identify individual tuples with a bool and at least one other value (which I called 'weight', and held inside the class itself)? Really what I'm going after is I need to have a group of information accessible (and editable) from a x and y coordinate. A dictionary would probably be the best way to do this, which is why I spent so much time trying to have a tuple as the key in a dictionary ... also I don't understand what your original two lines of code posted are supposed to be doing. BTW, I really do appreciate the help – brw59 Mar 17 '16 at 06:06