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
Related
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.
I need to make an 2d array, but c# won't let me and says that it is too big, any ideas how to make it work?
int[,] arrayName = new int[37153,18366];
The max theoretical size of an int array is 2147483647 i.e. int[] array = new int[2147483647] but the probleming you're having here is that the computer runs of out memory.
Read this for explanation and tips on how to solve this:
OutOfMemoryException on declaration of Large Array
If you are not using the complete range of the array (which is in your case 2,7GB of RAM), you could use a Dictionary.
https://msdn.microsoft.com/de-de/library/xfhwa508(v=vs.110).aspx
Alternative: Create a [][] Array. In this case you must initialize each row.
But you can access each cell easy with arrayName[row][col].
int[][] arrayName = new int[37153][];
for(int i=0; i<arrayName.Length; i++)
arrayName[i] = new int[18366];
The original problem is that I am reading big chunks of binary data from a tool that is being developed.
My goal is to read data and parse it to a human readable text such as a .csv file, so I have to flatten
that data.
The data is in form of samples of a multidimensional array of floats, longs or ints or whatever. And
because the tool is under development the size and dimensions of the array may differ from an hour to hour!
(e.g. right now I may have samples of a 2*2 matrix, two hours from now they may change the data struct to
1*4, or an array of 16*12*128,...)
One part of the problem is to generate the header line of the .CSV file. I need a method that can
generate an array of strings like this:
for a 2*2: data_0_0, data_0_1, data_1_0, data_1_1, and
for a 1*4: data_0, data_1, data_2, data_3,
for a 3*4*2: data_0_0_0, data_0_0_1, data_0_0_2,...., data_2_3_0, data_2_3_1,
and so on ...
The only information that I can get from the tool each time is the dimensions and size of the array.
The tool may tell me {1}, which means a single value, {12} means an array with a length of 12, {3,4,5}
means a " 3x4x5 " element array and so on and so forth... Therefore, I need to be able to flatten any array
of a*b*c*..*x. (which should not be too hard as I can have a single for loop.
So, I'd like to create a method that generates a vector of strings (in above format) from ANY multidimensional array.
Therefore I think at the end, the header generating method will lookalike something this
public string[] GenerateNames(string dataBlockName, int[] dimensions)
{
}
One simple solution is to have lets say 10 For-loops and hope that the raw data will never have an array that has more than 10 dimensions. However, I'm looking for a better, cleaner, nicer solution!
There are a lot of questions asking how to change a vector into multidimensional arrays. My goal is the exact opposite thing and a header line with unlimited flexibility!
Thanks a lot in advance fellas!
--
Someone below suggested to use "Depth First Traversal" which I am going to look into now. Initial googling seemed promising.
You can flatten any array by merely iterating it in a foreach loop, adding each item to a list, and then converting that list back to an array.
public T[] Flatten<T>(Array array)
{
var list = new List<T>();
foreach (T item in array)
{
list.Add(item);
}
return list.ToArray();
}
where array is a rectangular array of any shape.
You don't need the array with the size, as you can check the dimensions by using the Rank property of the Array class, and the corresponding methods for obtaining the values. With this in mind and the good old .net 1.0 Array class you can write a method like this one:
public T[] Flatten<T>(Array source)
{
var arrayIndex = new int[source.Rank];
var result = new T[Enumerable.Range(0, source.Rank).Sum(i => source.GetUpperBound(i))];
var index = 0;
for(var i = 0; i < source.Rank; i++)
{
for(var j = 0; j < source.GetUpperBound(i); j++)
{
arrayIndex[i] = j;
result[index++] = (T)source.GetValue(arrayIndex);
}
}
return result;
}
It's more convoluted than a foreach, but it will provide greater flexibility on how you could traverse the original array (which is dependent on the .net implementation). As Array is not a generic class you will need to provide the element type on the method, so that for an array of integers you can call it as:
Flatten<int>(myArray);
Buffer.BlockCopy is handy here.
Note: there are some special cases to deal with so take this as pseudocode.
public T[] Flatten<T>(Array source)
{
int byteCount = Buffer.ByteLength(source);
int sizeofT = Buffer.ByteLength(new T[1]);
T[] dest = new T[(byteCount + sizeofT - 1) / sizeofT];
Buffer.BlockCopy(source,0,dest,0,byteCount);
return dest;
}
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.
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.)