1

I know this is a really newbie question but it has thrown me for days and I can't seem to find a solution that I actually understand.

I am trying to make a nested array to store latitude and longitude, however it Xcode/playground throws a EXC_BAD_INSTRUCTION error.

I want to declare, initialise and print the contents of an array. What am I doing wrong?

var arrayLocations:[[Float]] = []

arrayLocations[0] = [27.1750199, 78.0399665]

print("\(arrayLocations[0][0]) and \(arrayLocations[0][1])")
Aecasorg
  • 165
  • 2
  • 13

3 Answers3

7

You cannot assign a value to index 0 because there is no index 0 if the array is empty.

You have to append or insert the item:

arrayLocations.append([27.1750199, 78.0399665])
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Super thanks! This is exactly what I was confused about. So basically you can't assign values to certain indexes, just add to them? – Aecasorg Jul 05 '17 at 06:29
  • You can only **update** values with index subscription. – vadian Jul 05 '17 at 06:32
  • Gotcha! Cheers! Oh and why does not the whole number show when printed? I used Float in order to keep the whole number intact. – Aecasorg Jul 05 '17 at 06:34
0

As vadian said on his answer

You cannot assign a value to index 0 because there is no index 0 if the array is empty.

You have to append or insert the item:

arrayLocations.append([27.1750199, 78.0399665])

I suggest that you make use of this Collection extension so that your code won't crash often

extension Collection where Indices.Iterator.Element == Index {
    
    /// Returns the element at the specified index if it is within bounds, otherwise nil.
    subscript (safe index: Index) -> Generator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

By using this you could just use if let blocks

Sample:

if let aLocation = arrayLocations[safe: 0] {
    aLocation = [27.1750199, 78.0399665]
}

This ensures that even if you try to access an object of index 0 your code won't crash.

Suggestion:

Note: This suggestion is not part of the answer, but rather something to improve your code.

It looks like you're trying to create an array of latitude and longitude. Using an array for the latitude and longitude object isn't very wise. I suggest that you create an object instead, it can be a struct or a typeAlias

For example:

struct CoordinateStruct {
    var longitude: Float
    var latitude: Float
}

/* or */

typealias CoordinateTypeAlias = (latitude: Float, longitude: Float)

/************************* */

// Your code would then look like this
var arrayLocations:[CoordinateStruct] = []
arrayLocations.append(CoordinateStruct(longitude: 27.12312312, latitude: 78.123123))

/* or */ 

var arrayLocations:[CoordinateTypeAlias] = []
arrayLocations.append((27.12312312, 78.123123))

// Which would make accessing them very easy and readable, like this.

if let aLocation = arrayLocations[safe: 0] {
    print(aLocation.longitude)
    print(aLocation.latitude)

    // instead of this 
    print(aLocation[0]) // a person who reads your code won't understand this
    print(aLocation[1]) // a person who reads your code won't understand this
}
Community
  • 1
  • 1
Zonily Jame
  • 5,053
  • 3
  • 30
  • 56
  • Please don't forget to add a link to the original source if you copy code from another answer (perhaps from https://stackoverflow.com/a/30593673/1187415 or https://stackoverflow.com/a/40331858/1187415?) – Martin R Jul 05 '17 at 07:08
  • @MartinR I added it, look at the top where I said `As vadian said on his answer` it's hyperlinked – Zonily Jame Jul 05 '17 at 07:09
  • I meant the `subscript (safe index: Index)` method ... – Martin R Jul 05 '17 at 07:10
  • @MartinR oh, sorry about that I didn't know where it came from. I'll edit my answer. – Zonily Jame Jul 05 '17 at 07:11
  • Thanks again for the extended answer! Really appreciated. Your suggestion is way above my level at the moment but something I need to learn and understand. @MartinR. To the untrained eye, the duplicate answer you mentioned at the top makes no sense to what I was asking. I came across it, but failed to see the relevance. I still can't see it, unless someone explains it to me. So why is my question "already answered"? Hopefully when I get to a higher knowledge level I will see it. :) – Aecasorg Jul 05 '17 at 07:40
  • 1
    @Aecasorg: You try to append a value to the array via subscripting: `arrayLocations[0] = ...` crashes if the array is empty. That is exactly the same error as in the Q&A that I linked to, and the solution is to use `append` or `+=` instead, as explained in the answers to that Q&A. – If you search for *"You can’t use subscript syntax to append a new item to the end of an array"* then you'll find even more duplicates. – Martin R Jul 05 '17 at 07:43
  • @MartinR Ok, sure, thanks! My Google search was "Swift nested array EXC_BAD_INSTRUCTION". I suspect many people at my level of programming knowledge would search in a similar fashion. Even when that link came up, I'm not experienced enough to see the similarities or that it is really about the same problem. "subscripting"... first time I hear about it. :P I thought I could just assign variables directly to specific "slots". I now know that it has to be added afterwards, however you access it and change it if it already there. – Aecasorg Jul 06 '17 at 13:10
0

You cannot assign value into 0 position because index 0 is empty.

You can do this in following ways -

With initial value -

var arrayLocations:[[Float]] = [[0.00,0.00]]

arrayLocations[0] = [27.1750199, 78.0399665]

print("\(arrayLocations[0][0]) and \(arrayLocations[0][1])")

Otherwise you can do this using append or insert as vadian's answer.

Thili77
  • 1,061
  • 12
  • 20