Trying to make a 2D array of lists

I am trying to write a model containing digital organisms. Within the framework of the model, I would replace the medium with a fixed 2-dimensional array, but each cell should contain a list of organisms in it. I tried using a jagged array, but as the number of occupied elements varies greatly during program execution, I need to use something more flexible than the array. I tried to make a 2-D array of type list, but im was getting errors with it.

List<Creature>[,] theWorld; public Environment() { List<Creature>[,] theWorld = new List<Creature>[100,100]; } public void addCreature(Creature c) { for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { theWorld[x, y].Add (c); } } } 

this is the segment where I try to declare an array at the beginning, as a type that contains lists (from organisms), and then I try to add a creature (c) to each of the lists in each element of the array.

when I run it, I get the following error message -

"In HGT_sim_2.exe

An unhandled exception of type "System.NullReferenceException" occurred.

Additional information: The reference to the object is not installed in the instance of the object. "

and the string "World [x, y] .Add (c);" stands out.

If someone tells me what I'm doing wrong, and even better, a way to solve the problem, it will be awesome. Thank you for the advance!

+6
arrays list c #
source share
6 answers

Your entire array contains initially many zeros. You need to create lists ...

 for(int x = 0 ; x < 100 ; x++) for(int y = 0 ; y < 100 ; y++) theWorld[x,y] = new List<Creature>(); 

Personally, however, I expect this to be an expensive way to do something ...

Partly depends on whether the data is "sparse" - i.e. are most of the commonly taken cells? For example, a simple (but possibly more effective) approach would be to use something like a multicard; i.e.

 Point pt = new Point(x,y); theWorld.Add(pt, someCreature); 

where theWorld could be something like EditableLookup<Point, Creature> (using EditableLookup<,> from MiscUtil "). So you can request it for coordination and have multiple creatures in coordinate, but you don't need to allocate space for each cell And since it functions like a dictionary, it’s still fast. Not as fast as a flat array, but it will scale to larger (sparse) grids ... of course, if there are creatures on each cell in the grid, it could be more expensive! From here you need to understand your data.

+7
source share

You need to initialize each element of your array, for example

 for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { theWorld[x, y] = new List<Creature>(); } } 
+3
source share

Here's the fix:

 List<Creature>[,] theWorld; public Environment() { theWorld = new List<Creature>[100,100]; // Remove the type, you were creating a new list and throwing it away... for(int x = 0 ; x < 100 ; x++) for(int y = 0 ; y < 100 ; y++) theWorld[x,y] = new List<Creature>(); } public void addCreature(Creature c) { for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { theWorld[x, y].Add (c); } } } 
+2
source share

You created an array object to store your lists, but you yourself did not create a list. You will need to do the following in your constructor:

 for (int x = 0; x < 100; x++) for (int y = 0; y < 100; y++) theWorld[x,y] = new List<Creature>(); 

Another problem: you also defined theWorld as a local variable in your constructor, which means that your theWorld field on the Environment also not initialized.

However, a 10,000 List may be redundant for what you really need. If your environment really requires Creature at every point, and some Creatures can move to other points (where there are more than one, they may make sense to use Dictionary<Point, IList<Creature>> as your model against 10,000 lists .

 public void Add(Creature c, Point at) { IList<Creature> list; if (!theWorld.TryGetValue(at)) { list = theWorld[at] = new List<Creature>(); } list.Add(c); } 

Then you can implement the Move and Remove methods in the same way. Also note that you are adding the same Being to each point, which (maybe) means that there is one Being at all points in your environment. You will probably want to create new Creature() for each point, if that is what you are actually modeling.

0
source share

When you do this:

 List<Creature>[,] theWorld = new List<Creature>[100,100]; 

You create an array of List<Creature> links, but they are all empty (pointing to null, not a valid list). You need to initialize each individual element:

 for (int x = 0; x < 100; x++) { for (int y = 0; y < 100; y++) { theWorld[i,j] = new List<Creature>(); } } 

Once you do this, you can call .Add for individual members.

0
source share

You do it almost right. Your variable is a 2D List<Creature> array. List<Creature> is now a reference type, so an array containing null in all its members is initialized. So you get a NullReferenceException . Line

 theWorld[x, y].Add (c); 

basically equivalent

 null.Add (c); 

All you have to do is initialize all members to contain List<Creature> instances. The best way to do this is in the constructor. Just rewrite it as follows:

 public Environment() { theWorld = new List<Creature>[100,100]; for(int x = 0 ; x < 100 ; x++) for(int y = 0 ; y < 100 ; y++) theWorld[x,y] = new List<Creature>(); } 

Now all operations will work as expected.

Also note that in your example, you create a local variable with the same name as the class member. Thus, you do not initialize a member of the class at all - it remains zero.

0
source share

All Articles