Im developing a small app/game in Unity3D.
The problem is:
I need to clone an array (call it tempArray) and make some modifications to it. Then i need to change values of the MAIN array to modified tempArray. However, whenever i make changes to cloned array, the same changes are made to the main one.
So i used the following code:
private Cell[,] allCells = new Cell[256, 256];
private Cell[,] cellClone = new Cell[256,256];
//meanwhile initiated to some values//
//Here i clone the array.
cellClone = (Cell[,])allCells.Clone();
//Here i output the values for an element from both arrays.
Debug.Log(cellClone[0, 0].region.name.ToString());
Debug.Log(allCells[0, 0].region.name.ToString());
//Here i want to change "Region" variable of cellClone ONLY.
cellClone[0, 0].setRegion(new Region("testregion123", Color.cyan, false));
//Finally, i output the same values again. Only cellClone should change.
Debug.Log(cellClone[0, 0].region.name.ToString());
Debug.Log(allCells[0, 0].region.name.ToString());
However, the output shows that allCells[0,0] element was also changed. This means that any operation I do to the cloned array, is executed to the main array.
EDIT:
After alot of playing around I implemented this as a solution. Im posting this in case anybody has a similar problem.
But Im not sure if this is how its supposed to be done so if anybody has any information - Ill be checking this post.
for (int i = 0; i < allCells.GetLength(0); i++)
{
for (int j = 0; j < allCells.GetLength(1); j++)
{
//cellClone[i, j] = allCells[i, j].Clone();
//cellClone[i, j] = new Cell((int)allCells[i, j].position.x, (int)allCells[i, j].position.y, allCells[i, j].getRegionName());
cellClone[i, j] = allCells[i, j].clone();
}
}
And the clone function:
public Cell clone()
{
Cell n = new Cell((int)position.x, (int)position.y, regionName);
return n;
}
However, the output shows that allCells[0,0] element was also changed. This means that any operation I do to the cloned array, is executed to the main array.
Unless Cell is a struct, your setRegion method (which sounds like it should really just be a Region property) isn't changing the contents of the array at all. It's changing the data stored in the object that both arrays contain a reference to.
You're performing a shallow clone of the array, which means the references are being copied - but each Cell object is not being cloned. (We don't even know whether that operation has been implemented within Cell.)
It sounds like you want to perform a deep clone, something like:
for (int i = 0; i < allCells.GetLength(0); i++)
{
for (int j = 0; j < allCells.GetLength(1); j++)
{
cellClone[i, j] = allCells[i, j].Clone();
}
}
... where you'd need to implement the Clone method yourself. (It may need to clone the region in turn, for example.)
Check this out:
Array.Copy
Array.Copy (Array, Array, Int32)
Easier and only 1 line of code;
Related
My program has to place objects on a map, i have to get the informations about the objects from a text file but my problem is that there is no limit in objects so when i write my code i don't know if someone wants to place 1 or 10 or 5 objects. Every object has a separate line where you can give the parameters for example x,y coordinates on the map to place etc etc.
I figured out that i will ask the user to write in a line before the objects the number of objects he wants to add.Here is my example :
txt file:
200<----not important here
10000<----not important here
5<---number of objects
2,5/60-60<--object
4,5/70-70<--object
5,5/80-80<--object
1,1/30-30<--object
10,10/100-100<--object
10,1/5<----not important here
height,weight/x-y
And vs throws out of range exception. Hope u understood my english and my problem
int numberofObjects = int.Parse(data[2]);
Targets[] TargetsGet = new Target[numberofObjects];
int j = 0;
for (int i = 4; i <= numberofObjects+3; i++)
{
targets[j] = new Target(int.Parse(data[i].Split(',')[0]), int.Parse(data[i].Split('/')[0].Split(',')[1]), new Coordinate(int.Parse(data[i].Split('/')[1].Split('-')[0]),int.Parse( data[i].Split('-')[1])));
j++;
}
return TargetsGet;
}
First of all, your solution works.
If you don't want to ask the user to specify the number of objects, you can use a list instead of an array and use a separator at the end of the object list. For example:
List<Targets> TargetsGet = new List<Target>();
int j = 0;
while(data[j]!="separator")
{
targets.Add(new Target(int.Parse(data[j].Split(',')[0]), int.Parse(data[j].Split('/')[0].Split(',')[1]), new Coordinate(int.Parse(data[j].Split('/')[1].Split('-')[0]),int.Parse( data[j].Split('-')[1])));
j++;
}
return TargetsGet.ToArray();
}
The file should be modified so the string "separator" will be after the object list:, for example:
200<----not important here
10000<----not important here
2,5/60-60<--object
4,5/70-70<--object
5,5/80-80<--object
1,1/30-30<--object
10,10/100-100<--object
separator
10,1/5<----not important here
height,weight/x-y
I have list called “images” which is contained of the series of bitmap images.
My question is how can I loop through every single element of my “images” list and do this operation for different elements of my list “images”?
You want to keep collections for each element of images, right?
You'll need to maintain a list of lists, or something similar:
List<List<int>> stuffOfImages = new List<List<int>>();
for (int x = 0; x < images[i].Width; x++) {
var stuffOfImage = new List<int>();
stuffOfImages.Add(stuffOfImage);
for (int y = 0; y < images[i].Height; y++) {
}
}
Note that you lose all reference to the associated image - it might be worthy creating a type so you can keep a reference to the image and the integer collection associated with it in one place and related.
I'm a little unclear as to what you mean, so please elaborate if necessary.
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)
I have array defined like this :
List<DocumentFields>[,] dummyArray = new List<DocumentFields>[8,8];
It takes records from the database. I need to prepare this array for showing in a asp.net mvc3 view so i iterate it the standard way :
for (int i = 0; i < ViewBag.Header.GetLength(0); i++)
{
for (int j = 0; j < ViewBag.Header.GetLength(1); j++)
{
But I realized that in fact for the second iteration I don't need the Length but the count of the elements that are actually there. So instead of ViewBag.Header.GetLength(1) I need this:
ViewBag.Header.Get_Count_Of_The_Elements_For_The_Second_Index
I couldn't find a property that do this right away. Maybe some way of using Length or something... Dunno...
Your dummyArray is a two-dimensional array of lists. To get list size you can use dummyArray[i,j].Count in your inner loop.
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.)