I have an array with 3 integers. I want to duplicate the array and change the first integer. For some magical reason, BOTH arrays get their first integer adjusted. I have no idea why this is happening and it's driving me crazy.
int [] numbers1 = {1, 2, 3}
int [] numbers2 = {3, 4, 5}
numbers2 = numbers1;
At this point I did a System.Console.Writeline to see both arrays are now {1, 2, 3}. So far so good.
numbers1[0] = 4;
When I'm doing a System.Console.Writeline I see BOTH arrays now look like {4, 2, 3}. I want numbers2 to stay the same.
Currently you are only passing a reference. The numbers in the array are stored in memory. When you reference an object in memory it points to that object. It does not create a new object in memory when referencing, so you need to clone the ints into another array so that it points to a different object in memory.
numbers2 = numbers1;
You need to clone the arrays.
numbers2 = (int[])numbers1.Clone();
As others have noted you can also use the .ToArray() method. This creates a copy of the items in the array.
numbers2 = numbers1.ToArray();
Arrays are a reference-type, regardless if the values of an array are value-types.
When you allocate an array you are creating a block of memory that the array variable points to. When you assign one array variable to another you are assigning the memory reference, not the values in the array. So both of your numbers1 and numbers2 arrays are pointing to the same set of values.
Now this should make sense. Imagine if you have an array with a million elements then every time you assigned or passed the array around you made a copy it would be an horrific performance issue.
So, you need to explicitly say when you want to copy an array.
The easiest way is to do this:
numbers2 = numbers1.ToArray(); // yes, this copies the entire array.
Using this:
numbers2 = numbers1;
You are assigning the reference of first array to the second array. So it loses your original contents and start pointing to numbers1. If you want to copy few or all items of numbers1 to numbers2 then either use Clone() or use loop to copy elements.
Did you try .ToArray() method? It will create new array not assign by reference Array2= Array.ToArray(); Click here for more about .ToArrray()
try to use the .ToArray(); or Clone its work for me
my suggestion is .ToArray();
Related
Say I have a 3d array:
int[,,] arr = new int[3, 2, 3];
How can I delete all items under one of the first dimension? And if that can be done, will that move up all the values under it? Or will the deleted items just take null values and be counted in the arr.GetLength(0) method?
I've found a C# version of the Visual Basic's ReDim method. https://stackoverflow.com/a/327958/9076546
Note that dynamic array sizes aren't the best for performance. ReDim was a mistake in my honest opinion...
var mylist1 = new List<float>(5);
var mylist2 = new List<float>(new float[5]);
mylist1 gets 5 as a capacity. mylist2 gets 5 too. What is the difference between these two and which one should I use?
The first declaration creates a list with an underlying array with a size of 5.
The second declaration copies data from the passed array to the underlying array in the list.
So the second declaration needs to:
Create an empty array
Copy the values in that array to another array
Since it's also harder to read (what's the point of passing an empty array to a list constructor?), there really isn't any reason at all to use the second instead of the first.
The reason the overload is there is to allow you to prefill the list with values from another array or enumerable. For example:
var list = new List<int>(Enumerable.Range(1, 100));
(though of course, even then you'd usually use Enumerable.Range(1, 100).ToList() instead :))
The first create a List having capacity 5, but empty.i.e, if you access myList1[3] you get an error.
The second create a List of float containing already 5 elements. each element will have value 0.0, i.e the default value for a float
I have tried
int[] secondArray = firstArray;
but whenever I alter the first array it changes in the second, is there a function that allows me to alter the first without it affecting the second?
Thanks.
That's because you have an object that is an "array of integer" which firstArray references. Your assignment statement just increments the reference count of the object
I think what you may be looking for is a way to provide a shallow copy of the firstArray? If so, use the clone method
Like Tim said, you need to understand why this happens, so read up on it. :)
But you could use the Array.CopyTo method:
int[] firstArray = new int[20];
int[] secondArray = new int[20];
firstArray.CopyTo(secondArray, 0);
But you will have to make sure that you wont overflow the second array yourself, because otherwise, it will throw an exception.
I have a char array in C#.
var arr = new char[3] { 'a','b','c' };
How do I add spaces to the end of it without creating a new array?
result: arr = { 'a', 'b', 'c', ' ', ' ', ' ' };
This might sound similar to VB.NET's ReDim. But I'm not sure that is what I want either.
I want to preserve the elements inside of it and not instantiate a new array behind the scenes.
Is this only possible with Generic Collections and ArrayList?
Thanks
No, this is not possible using an array, generic or otherwise.. AFAIK, there is no way to dynamically resize an array. Use a List instead.
As Martin pointed out in the comments, even the List class uses an array in its internal implementation. If you want to truly be able to dynamically resize a data structure without reinitializing it, you must implement your own version of a linked list.
System.Collections.Generic contains a class called LinkedList that represents a doubly-linked list (meaning that each node has a reference to both the next and the previous node), but I'm not sure if its internal implementation uses an array..
Unfortunately, arrays are pre-fixed by design. This is important because it will reserve the necessary amout of memory at the heap.
So, to answer your requirement about not creating a new one: it won't be possible.
There is, however, a work-around. Look the following method:
Array.Resize(ref myArr, myArr.Length + 5);
It works as described at the source:
This method allocates a new array with the specified size, copies
elements from the old array to the new one, and then replaces the old
array with the new one.
If array is null, this method creates a new array with the specified
size.
If newSize is greater than the Length of the old array, a new array is
allocated and all the elements are copied from the old array to the
new one. If newSize is less than the Length of the old array, a new
array is allocated and elements are copied from the old array to the
new one until the new one is filled; the rest of the elements in the
old array are ignored. If newSize is equal to the Length of the old
array, this method does nothing.
This method is an O(n) operation, where n is newSize.
This means that myArr will be updated to reference the new array. However, if there is another reference to the original array, this won't be updated (it will keep referencing the older version).
Source: MSDN
I'm using jagged arrays and have a bit of a problem (or at least I think I do). The size of these arrays are determined by how many rows are returned in a database, so it is very variable. The only solution I have is to set the dimensions of the array to be very huge, but this seems ... just not the best way to do things.
int[][] hulkSmash = new int[10][];
hulkSmash[0] = new int[2] {1,2};
How can I work with jagged arrays without setting the dimensions, or is this just a fact of life with C# programming??
You've got 2 choices:
You can read the size of the information returned from the database, and allocate your array space at that time, once you know what you're getting.
Otherwise, what you're looking for is a data structure that has variable dimensions. Take a look at List for example: MSDN: List< T >
The other examples using List<T> and collections are the best way to proceed. I sometimes find the
List<List<int>> hulkSmash = new List<List<int>>();
syntax a tad unwieldy. Luckily, there are some options to manage this.
The first option I sometimes use is to make an alias:
using List<List<int>> = HulkSmashCollection;
This prevents you from having to do nested <<<Types>>> all the time. Everywhere you'd type List<List<int>> you can instead type HulkSmashCollection (or something shorter still) instead.
The second option is to wrap the List of Lists within a class called, say, MyHulkSmashes. Here, you only provide the functions/properties you need, like Count or Find() etc.
Both these concepts are used to reduce the amount of code on screen, and reduce perceived complexity.
List<List<int>> hulkSmash = new List<List<int>>();
hulkSmash.Add(new List<int>() { 1, 2 });
or
List<int[]> hulkSmash = new List<int[]>();
hulkSmash.Add(new int[] { 1, 2 });
A collection of ints (such as List) will give you the flexibility that you want and not waste space as would allocating an array that is much larger than you will ever need.