How to clear an array in Visual C# - c#

I have an array of ints. They start out with 0, then they get filled with some values. Then I want to set all the values back to 0 so that I can use it again, or else just delete the whole array so that I can redeclare it and start with an array of all 0s.

You can call Array.Clear:
int[] x = new int[10];
for (int i = 0; i < 10; i++)
{
x[i] = 5;
}
Array.Clear(x, 0, x.Length);
Alternatively, depending on the situation, you may find it clearer to just create a new array instead. In particular, you then don't need to worry about whether some other code still has a reference to the array and expects the old values to be there.
I can't recall ever calling Array.Clear in my own code - it's just not something I've needed.
(Of course, if you're about to replace all the values anyway, you can do that without clearing the array first.)

Related

How do I create an independent copy of an array in Unity?

TL;DR: I need a way to copy an array with integers, in which the copy will not change the original array, and that will work in Unity.
I am trying to implement the following algorithm: I have an array field with numbers that are editable in the inspector. These numbers indicate the number of enemies of each type to spawn:
public int[] EnemiesToSpawn;
And, for example, I set the array to 3 digits, the index of each in the array corresponds to the index of the object in the array with enemy prefabs.
Then, in the function, I randomly generate enemies, each time decreasing the corresponding number in the array by one (if the element integer is 0, another enemy is selected, and if the integer of all elements becomes 0, the spawn function ends execution).
Everything worked well until I needed to have multiple points on the level, each of which would generate enemies independently. What I did: I added another array, into which I copy the values ​​from the first one every time I need to spawn enemies at a new point, and edited this particular second array instead of the original one (simply by assigning the value via "="). Of course it didn't work, I googled it and realized that arrays in C # are stored as references, not values, so the original array was edited as well.
I tried a lot of options that offer for correct copying (such as System.Array.Copy and others), but for some reason none of them worked in Unity.
The only thing I came up with myself was iterating over in a loop and assigning values ​​separately:
EnemiesToSpawnCurrent = new int [EnemiesToSpawn.Length];
for (int i = 0; i <EnemiesToSpawn.Length; i ++)
{
EnemiesToSpawnCurrent [i] = i;
}
But, this code also does not work correctly for some reason, the numbers do not correspond to those entered in the inspector (most likely the indexes of the elements do not match).
I will be grateful if you tell me how you can optimally solve this problem.
Option A:
int[] a; // original array you want to deep copy
int[] b = new int[a.length]; // your copy
System.Array.Copy(a, b, a.length);
Option B:
int[] a; // original array you want to deep copy
int[] b = (int[]) a.Clone();
edit: in your code, the numbers won't match, because you are assigning them i.
EnemiesToSpawnCurrent = new int [EnemiesToSpawn.Length];
for (int i = 0; i <EnemiesToSpawn.Length; i ++)
{
EnemiesToSpawnCurrent [i] = i; // wrong!
}
this should work:
EnemiesToSpawnCurrent = new int[EnemiesToSpawn.Length];
for (int i = 0; i <EnemiesToSpawn.Length; i ++)
{
EnemiesToSpawnCurrent[i] = EnemiesToSpawn[i]; // copy each value from original to new Array.
}
Explanation: For int Array, this works because Integers are "Value type" and not reference Type. The whole array is Reference Type, so you need to create a new, independent instance. But assigning the values (ints) to the new array will work.
If you however want to copy something like Player[] you would need to create deep copies of the Player instances as well.

Entire array's values being overwritten with each iteration in for loop

I have a for loop that iterates through an object array to set the values for the drawing of the object. Below is the code
for (int i = 0; i < screenBottom.Length; i++)
{
int newPostion = i * screenBottom[i].sourceRect.Width;
//go through sourceRect as we're using drawSimple mode
screenBottom[i].sourceRect.X = newPostion;
screenBottom[i].Draw(spriteBatch);
}
However each time a new value for sourceRect.X is set the value of sourceRect.X for ALL the objects in the array is overwritten. By the end of the for loop the value for all sourceRect.X's is equal to what only the last value should be. Through some testing I found this ONLY happens in a loop. If I change the values outside of a loop such an occurrence does not happen. Please help!
I suspect the array contains the same object lots of times, i.e. accidentally:
SomeType[] screenBottom = new SomeType[n];
for(int i = 0 ; i < screenBottom.Length ; i++)
screenBottom[i] = theSameInstance;
You can check this simply with ReferenceEquals(screenBottom[0], screenBottom[1]) - if it returns true, this is the problem.
Note it could also be the case that all the array items are different, but that they all talk to the same sourceRect instance; you can check that with ReferenceEquals(screenBottom[0].sourceRect, screenBottom[1].sourceRect)

Modify multi Dimensional array

I have an Array variable. I can use the Rank property to get the number of dimensions and I know that you can use a foreach to visit each element as if the array was flattened. However, I wish to modify elements and change element references. I cannot dynamically create the correct number of for loops and I cannot invalidate an enumerator.
EDIT
Thanks for the comments, sorry about the previous lack of clarity at the end of a long tiring day. The problem:
private void SetMultiDimensionalArray(Array array)
{
for (int dimension = 0; dimension < array.Rank; dimension++)
{
var len = array.GetLength(dimension);
for (int k = 0; k < len; k++)
{
//TODO: do something to get/set values
}
}
}
Array array = new string[4, 5, 6];
SetMultiDimensionalArray(array);
Array array = new string[2, 3];
SetMultiDimensionalArray(array);
I had another look before reading this page and it appears all I need to do is create a list of integer arrays and use the overloads of GetValue and SetValue -
Array.GetValue(params int[] indices)
Array.SetValue(object value, params int[] indices)
Everything seems clear now unless someone can suggest a superior method. svick has linked to this so I will accept this answer barring any further suggestions.
It's hard to tell what exactly do you need, because your question is quite unclear.
But if you have a multidimensional array (not jagged array) whose rank you know only at runtime, you can use GetValue() to get the value at specified indices (given as an array of ints) and SetValue() to set it.

how to inset a new array to my jagged array

hello i will much apreciate any help.
ok let's see, first i have declare a jagged array like this and the next code
int n=1, m=3,p=0;
int[][] jag_array =new[n];
now my jagged array will have 1 array inside, next y have to fill the array like this:
car=2;
do
{
jag_array[p]= new double[car];
for (int t = 0; t < carac; t++)
{
jag_array[p][t] = variableX;
}
p=p+1
}
while(p==0)
now my jagged array looks like this(also insert some data for this example):
jag_array[0][0]=4
jag_array[0][1]=2
now my question how can i insert a new array whit out losing my previos data if i declare
jag_array[p+1]= new double[car];
i will lose the data from the previos one, i will like to look something likes this:
jag_array[0][0]=4
jag_array[0][1]=2
jag_array[1][0]=5
jag_array[1][1]=6
the reason i did not declare from the begining 2 array is beacuse i dont know how many i am going to use it could be just 1 or 20 and every time i have to create a new array whit out losing the previous data that has been already fill, thaks all for the attention,
The size of an array, once created, is by definition invariable. If you need a variable number of elements, use a List<T> - in your case, probably a List<int[]>.
The only alternative solution would be to created a new array with the new size (and assign that to your jag_array variable) and copy all the previous elements from your old array into the new array. That is unnecessarily complicated code when you can just use List<T>, but if you cannot use List<T> for any reason, here is an example:
// increase the length of jag_array by one
var old_jag_array = jag_array; // store a reference to the smaller array
jag_array = new int[old_jag_array.Length + 1][]; // create the new, larger array
for (int i = 0; i < old_jag_array.Length; i++) {
jag_array[i] = old_jag_array[i]; // copy the existing elements into the new array
}
jag_array[jag_array.Length - 1] = ... // insert new value here

Ways in .NET to get an array of int from 0 to n

I'm searching the way(s) to fill an array with numbers from 0 to a random. For example, from 0 to 12 or 1999, etc.
Of course, there is a for-loop:
var arr = int[n];
for(int i = 0; i < n; i++)
{
arr[i] = i;
}
And I can make this method been an extension for Array class. But is there some more interesting ways?
This already exists(returns IEnumerable, but that is easy enough to change if you need):
arr = Enumerable.Range(0, n);
The most interesting way in my mind produces not an array, but an IEnumerable<int> that enumerates the same number - it has the benefit of O(1) setup time since it defers the actual loop's execution:
public IEnumerable<int> GetNumbers(int max) {
for (int i = 0; i < max; i++)
yield return i;
}
This loop goes through all numbers from 0 to max-1, returning them one at a time - but it only goes through the loop when you actually need it.
You can also use this as GetNumbers(max).ToArray() to get a 'normal' array.
The best answer depends on why you need the array. The thing is, the value of any array element is equal to the index, so accessing any element is essentially a redundant operation. Why not use a class with an indexer, that just returnes the value of the index? It would be indistinguishable from a real array and would scale to any size, except it would take no memory and no time to set up. But I get the feeling it's not speed and compactness you are after. Maybe if you expand on the problem, then a better solution will be more obvious.

Categories