How to Assign an Array to a Class Property by Reference Rather Than a Copy

Is it possible to assign an array to a class property by reference rather than a copy?

The simple solution is to wrap the array in a class. The class instance is passed by reference so the problem is effectively solved: a change to the array through any reference to the class instance affects the array as seen through every reference to that class instance.

The class in question can be extremely lightweight - basically, it just serves as a thin wrapper that carries the array along with it, and a client accesses the array directly through the class instance - or, just the opposite, you can design the class to manage the array, i.e. the class deliberately presents an array-like API that shields clients from the underlying implementation. Either approach might be appropriate; I've certainly done both.

Here's an example of the first kind of situation. My model object is an array belonging to a UIDocument subclass. My view controller is a UITableViewController. The user is going to view, add, and edit model entities in the table. Thus, the UITableViewController needs access to the UIDocument's array (which happens to be called people).

  • In Objective-C, my UITableViewController simply held a reference to the array, self.people, which was an NSMutableArray. This was just a pointer, so changes to self.people were also changes to the UIDocument's people - they are one and the same object.

  • In Swift, my UITableViewController holds a reference to the UIDocument object, self.doc. The array, which is now a Swift array, is "inside" it, so I can refer to it as self.doc.people. However, that's too much rewriting! Instead, I've created a calculated variable property self.people which acts as a gateway to self.doc.people:

    var doc : PeopleDocument!
    var people : [Person] { // front end for the document's model object
    get {
    return self.doc.people
    }
    set (val) {
    self.doc.people = val
    }
    }

    Hey presto, problem solved. Whenever I say something like self.people.append(newPerson), I'm passed right through to the UIDocument's model object people and I'm actually appending to that. The code thus looks and works just like it did in Objective-C, with no fuss at all.

Copy array instead of simply assigning a reference on mapping

If I understand what you expect, I think you could use AfterMap to access both the source object and the destination object

this.CreateMap<Entity, Model>()
.ReverseMap()
.ForMember(destEntity => destEntity.RowVersion, opt => opt.Ignore())
.AfterMap((srcModel, destEntity) =>
{
for (int i = 0; i < srcModel.RowVersion.Length; i++)
{
destEntity.RowVersion[i] = srcModel.RowVersion[i];
}
});

How to initialize an array in a property's sub-class? (Object reference not set.... error)

Just instantiate / assign the address at the same time. Something like this should work:

req.quoterinput.consumer.addresses_attributes = new []
{
new Addresses_Attributes
{
zip = "53704"
}
};

Another way (since the property toy are trying to set is an Array), is to create a dynamic sized list, add to it, then convert it back during declaration.

var addresses = new List<Addresses_Attributes>
{
new Addresses_Attributes {zip = "53704"}
};

req.quoterinput.consumer.addresses_attributes = addresses.ToArray();

Or, you can assign it an array of size 1, and then set it up from there:

    req.quoterinput.consumer.addresses_attributes = new Addresses_Attributes[1];
req.quoterinput.consumer.addresses_attributes[0] = new Addresses_Attributes { zip = "666" };

Copying of an array of objects to another Array without object reference in javascript(Deep copy)

Let me understand: you don't want just have a new array, but you want to create a new instance for all objects are present in the array itself? So if you modify one of the objects in the temp array, that changes is not propagated to the main array?

If it's the case, it depends by the values you're keeping in the main array. If these objects are simple objects, and they can be serialized in JSON, then the quickest way is:

var tempArray = JSON.parse(JSON.stringify(mainArray));

If you have more complex objects (like instances created by some your own constructors, html nodes, etc) then you need an approach ad hoc.

Edit:

If you don't have any methods on your newObjectCreation, you could use JSON, however the constructor won't be the same. Otherwise you have to do the copy manually:

var tempArray = [];
for (var i = 0, item; item = mainArray[i++];) {
tempArray[i] = new newObjectCreation(item.localIP, item.remoteIP, item.areaId);
}

Are arrays in PHP copied as value or as reference to new variables, and when passed to functions?

For the second part of your question, see the array page of the manual, which states (quoting) :

Array assignment always involves value
copying. Use the reference operator to
copy an array by reference.

And the given example :

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
// $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>



For the first part, the best way to be sure is to try ;-)

Consider this example of code :

function my_func($a) {
$a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

It'll give this output :

array
0 => int 10
1 => int 20

Which indicates the function has not modified the "outside" array that was passed as a parameter : it's passed as a copy, and not a reference.

If you want it passed by reference, you'll have to modify the function, this way :

function my_func(& $a) {
$a[] = 30;
}

And the output will become :

array
0 => int 10
1 => int 20
2 => int 30

As, this time, the array has been passed "by reference".



Don't hesitate to read the References Explained section of the manual : it should answer some of your questions ;-)

Get reference to variable and avoid copying it unnecessarily

You could create a public property that returns the last element of arrays.

class ArrayOfArrays
{
Array[] arrays;

public Array LastOfArrays { get { return arrays.Last(); } }
}

Test it:

var aoa = new ArrayOfArrays();
// Initialize and enter data here

//When you want to use the last item:
var last = aoa.LastOfArrays;
last.values[0] = 333;

Now, aoa.arrays[LastElement].values[0] would also be 333. So you essentially do keep the reference here, and does not copy the entire array.

Confirmation:

Sample Image

Passing Arrays by Value and by Reference

The key to understanding this is to know the difference between a value type and a reference type.

For example, consider a typical value type, int.

int a = 1;
int b = a;
a++;

After this code has executed, a has the value 2, and b has the value 1. Because int is a value type, b = a takes a copy of the value of a.

Now consider a class:

MyClass a = new MyClass();
a.MyProperty = 1;
MyClass b = a;
a.MyProperty = 2;

Because classes are reference types, b = a merely assigns the reference rather than the value. So b and a both refer to the same object. Hence, after a.MyProperty = 2 executes, b.MyProperty == 2 since a and b refer to the same object.


Considering the code in your question, an array is a reference type and so for this function:

public static void FirstDouble(int[] array)

the variable array is actually a reference, because int[] is a reference type. So array is a reference that is passed by value.

Thus, modifications made to array inside the function are actually applied to the int[] object to which array refers. And so those modifications are visible to all references that refer to that same object. And that includes the reference that the caller holds.

Now, if we look at the implementation of this function:

public static void FirstDouble(int[] array)
{
//double each elements value
for (int i = 0; i < array.Length; i++)
array[i] *= 2;

//create new object and assign its reference to array
array = new int[] { 11, 12, 13 };
}

there is one further complication. The for loop simply doubles each element of the int[] that is passed to the function. That's the modification that the caller sees. The second part is the assignment of a new int[] object to the local variable array. This is not visible to the caller because all it does is to change the target of the reference array. And since the reference array is passed by value, the caller does not see that new object.

If the function had been declared like this:

public static void FirstDouble(ref int[] array)

then the reference array would have been passed by reference and the caller would see the newly created object { 11, 12, 13 } when the function returned.

PHP 5 | Objects Passed by Reference / Value vs Copy on Write | When added as class property

As the manual page you link to says, the statement "objects are passed by reference" is not a good description of what is happening. A better way to think of it is that the "value" of an object is a handle, pointer, or address to something that exists in a different space.

Whether you assign it to an object property, an array element, or a normal variable, this "value" remains the same, and changes to the object are visible wherever you look at them. Copying the value uses a few bytes (the size of the pointer) but doesn't duplicate the memory of the object itself.

As a final clarification, the "write" in "copy-on-write" refers to modification of an existing value, after copying it from one place to another. So writing $foo = $bar, where $bar is an array, will not duplicate the memory used by the array, but subsequently writing $foo[0]=1; or $bar[0]=1 will, because the two copies need to be distinguished. This doesn't actually come into play in your example; if it did, it would be just the "object pointer" that was copied, so very little extra memory would be needed.



Related Topics



Leave a reply



Submit