1

In Javascript, when you do that :

var a = [1, 2];

var b = a;

b.push(3);

console.log(a); //Print [1, 2, 3]

a and b share the same array instance. I am looking for a way to achieve this in Swift

Here is my Swift code :

var array1 = [[1], [2], [3]];

var array2 = array1[0];

array2.append(0);

print(array1);
//print [[1], [2], [3]]
//I want [[1, 0], [2], [3]]

array1[0] & array2 are two different instances ... I'd like two variables (with different names) pointing to the same instance of an array.

Santa Claus
  • 984
  • 1
  • 12
  • 26
  • 1
    Arrays are value types in Swift, you cannot share the same instance with another. – Santosh Nov 28 '16 at 21:58
  • Oh that's sad ... Maybe a kind of pointer variables ? Does it exist ? – Santa Claus Nov 28 '16 at 22:01
  • 3
    Related: [Pass array by reference between viewcontrollers in swift](http://stackoverflow.com/q/32049202/2976878), [Is it possible to assign an array to a class property by reference rather than a copy?](http://stackoverflow.com/questions/25533122/is-it-possible-to-assign-an-array-to-a-class-property-by-reference-rather-than-a) – Hamish Nov 28 '16 at 22:03

1 Answers1

2

You have to wrap a value type into a reference type ie class.

class wrapper {
    var array = [1,2]
}

var a = wrapper()

var b = a

b.array.append(3)

print(a.array) // [1,2,3]

Reading here You can also use NSMutableArray

var c : NSMutableArray = [1,2]


var d = c

d.insert(3, at: 2)

print(c) //"(\n    1,\n    2,\n    3\n)\n"
Community
  • 1
  • 1
mfaani
  • 33,269
  • 19
  • 164
  • 293
  • I'm not sure as to which is faster/better, but I think if you only want an array, then using NSMutableArray is preferred, but if you want a model, ie something that also stores an array and needs to be persisted then perhaps wrapping it inside a class is a better choice. – mfaani Nov 28 '16 at 22:13
  • 3
    A wrapper type is far better, as you don't throw away the type information of what the elements are, unlike `NSMutableArray` (and you don't needlessly bridge the elements over to Obj-C). You can make the wrapper generic in order to store different types of arrays, such as shown in [Qbyte's answer here](http://stackoverflow.com/a/32050164/2976878). – Hamish Nov 28 '16 at 22:15
  • @Hamish Faster because no bridging? OK. What do you mean when you say *"don't throw away the type information"* you mean generics? – mfaani Nov 28 '16 at 22:21
  • 1
    I mean that in your example `wrapper` contains an `array` property of type `[Int]`, therefore you know that it contains only `Int`s. `NSMutableArray` on the other hand just contains heterogeneous `NSObject`s (bridged back to Swift as `Any`) – the elements could be a mix of `NSNumber`s, `UIView`s and `UIColor`s for all we know. Therefore you'll have to do some type-casting before you can do anything useful with them. – Hamish Nov 28 '16 at 22:26
  • Thanks. I understand the concept now. *"therefore you know that it contains only Ints"*. So in my answer, I **am** throwing the type information ie I'm saying it's of type **Int**. I feel like my jargon is different than yours. Why did you say " as you **don't** throw away" – mfaani Nov 28 '16 at 22:30
  • I was talking about the wrapper type when I said "*you don't throw away the type information*" – which you don't, as with a native Swift array, you have to tell the compiler what type the elements are. – Hamish Nov 28 '16 at 22:35
  • I initially thought by throwing you meant 'throw int' *specifying* it as [int] but then now reading into all of this over the course of several hours I realize you meant, throwing away as in making in something heterogeneous which would later requires us to downcast it...losing the performance of a strongly typed language. – mfaani Nov 29 '16 at 03:28