1

I'm new to swift and I haven't programmed much at all lately. I'm trying to assign an array from an array of arrays to a variable. But as far as I can tell, i only get a copy of that array (so that if the member of the array of arrays later changes, the copy doesn't. How do I get a reference to the original object?

Here is some code (included before "class ViewController: UIViewController" in an effort to get global variables):

var g1 = [2,0,0,0,0]
var g2 = [2,0,0,0,0]
var g3 = [2,0,0,0,0]
var g4 = [3,0,0,0,0]
var g5 = [3,0,0,0,0]
var g6 = [4,0,0,0,0]
var g7 = [5,0,0,0,0]

let groids: Array = [g1, g2, g3, g4, g5, g6, g7]

Later, as part of some function, I want to assign a variable "a" one of the members of groids, but as I stated not a copy of that member but that member itself. How do I do this? Please bear in mind that I have little programming experience.

3 Answers3

2

You don't get a reference to the “original object”, because in Swift, arrays are not reference types; they are value types. This means they act as if they are always copied. (Under the hood, things are implemented more efficiently, but the design is that they appear to always be copied.)

If your only prior experience is in languages that treat arrays as reference types (which means pretty much every popular language like C, C++, C#, Java, Python, Ruby, JavaScript, etc.), this can take a while to get used to.

Here are some alternatives:

  1. Use NSArray instead of Array. NSArray is a reference type.

  2. Pass around the array indexes you're interested in, or a KeyPath. KeyPath is documented in The Swift Programming Language.

  3. Use inout arguments, which are also documented in The Swift Programming Language.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Thank you! This was helpful. I tried the first route, got some errors, overcame them, but then got stuck on print(groids[1][2] + groids[1][4]) (which worked for the array) generating the error message "Type 'Any' has no subscript members". How do I overcome this? I consulted https://developer.apple.com/documentation/foundation/nsarray but didn't really understand enough to get unstuck. – ProfessorHelloKittyNr1 May 08 '18 at 17:27
  • If `groids` is an `NSArray`, `groids[1]` has type `Any`. Try `(groids[1] as! NSArray)[2] as! Int`. – rob mayoff May 08 '18 at 17:39
0

So you want to change an element in groids and have the change reflect in the arrays g1-7?

groids[3] = [1,2,3,4,5]
// g4 now becomes [1,2,3,4,5]

Well, first of all, groids is a constant so you can't mutate it. Let's assume that you changed it to var.

In fact, you don't need g1-7 at all. You can remove those variables and just declare groids like this:

var groids = [
    [2,0,0,0,0],
    [2,0,0,0,0],
    [2,0,0,0,0],
    [3,0,0,0,0],
    [3,0,0,0,0],
    [4,0,0,0,0],
    [5,0,0,0,0],
]

And you can access g1 to g7 by doing groids[0] to groids[6].

You can also declare g1 to g7 as computed properties, but I don't see much point in doing that:

var g1: [Int] {
    return groids[0]
}

Also, you might want to consider creating a struct or class to store these 5 numbers if these 5 numbers represent some kind of structured data.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

There are a few things that I see as problematic in your code. First, groids is a let, which means it is a constant, so it wouldn't be changeable. in swift var is used to indicate variables and let is used to indicate constants. Second, global variables are rarely desirable and without good reason should be avoided, so make sure you actually want global variables because there are known for causing unwanted side effects and making code functionality unclear, and if you want them to be global they should be prefixed with public static so everything has access to them. also, passing by value of objects is talked about here. As for letting var a = some global, I would suggest initializing groids as the only global, if it does indeed need to be global, and then using indexes of that to access the different inner arrays. One possible solution is:

let g1:[Int] = [2,0,0,0,0]
let g2:[Int] = [2,0,0,0,0]
let g3:[Int] = [2,0,0,0,0]
let g4:[Int] = [3,0,0,0,0]
let g5:[Int] = [3,0,0,0,0]
let g6:[Int] = [4,0,0,0,0]
let g7:[Int] = [5,0,0,0,0]

public static var groids:[[Int]] = [g1, g2, g3, g4, g5, g6, g7]

//In the place a is assigned
var a:[Int] = groids[0]

Or instead of using "a", just use groids because it is global, that way you know you are always accessing the same variable or array.

Pasosta
  • 825
  • 3
  • 13
  • 22