Bramble
Bramble

Reputation: 1395

Multi-Dimensional Data Structures in C#

How do you create a multi-dimensional data structure in C#?

In my mind it works like so:

 List<List<int>> results = new List<List<int>>();
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            results[i][j] = 0;
        }
    }

This doesn't work (it throws an ArgumentOutOfRangeException). Is there a multi-dimensional structure in C# that allows me to access members through their indexes?

Upvotes: 1

Views: 1126

Answers (5)

Pavel Minaev
Pavel Minaev

Reputation: 101665

If you know the dimensions of your structure in advance, and you do not plan to add or remove elements, then a 2D array sounds like your thing:

int[,] n = new int[10, 20];
for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 10; ++j) {
        n[i, j] = ...
    };
};

Upvotes: 3

Zooba
Zooba

Reputation: 11458

The problem here is that List doesn't automatically create elements. To initialise a List<List<T>> you need something like this:

List<List<int>> results = new List<List<int>>();

for (int i = 0; i < 10; i++)
{
    results.Add(new List<int>());
    for (int j = 0; j < 10; j++)
    {
        results[i].Add(0);
    }
}

Note that setting Capacity is not sufficient, you need to call Add the number of times you need. Alternatively, you can simplify things by using Linq's Enumerable class:

List<List<int>> results = new List<List<int>>();

for (int i = 0; i < 10; i++)
{
    results.Add(new List<int>());
    results[i].AddRange(Enumerable.Repeat(0, 10));
}

Again, note that Enumerable.Repeat(new List<int>(), 10) will not work, since it will add 10 references to the same list.

Another approach using Linq to the extreme:

List<List<int>> results = Enumerable.Repeat(0, 10)
    .Select(i => Enumerable.Repeat(0, 10).ToList())
    .ToList();

(The unused parameter i is necessary to ensure that you don't reference the same list ten times as discussed above.)

Finally, to access elements, you can use exactly the notation you used before. Once the elements have been added, they can be read or modified as shown:

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        results[i][j] = 2;
        int x = results[i][j];
    }
}

Upvotes: 10

Chris Pitman
Chris Pitman

Reputation: 13104

You have to actually 1) create each of the inner lists, and 2) set them to that size.

var Results = Enumerable.Range(0, 10).Select(i => Enumerable.Repeat(0, 10).ToList()).ToList();

I'm a bit of a Linq addict, though.

Upvotes: 2

Mark Byers
Mark Byers

Reputation: 839074

You have to create the lists and initialize them with zeros before you can't start indexing into them.

    List<List<int>> results = new List<List<int>>();

    for (int i = 0; i < 10; i++)
    {
        results.Add(new List<int>(Enumerable.Repeat(0, 10)));
    }

Upvotes: 2

RiddlerDev
RiddlerDev

Reputation: 7469

You could use a datatable and add columns and rows? You would then be able to reference them by name or index.

Upvotes: 0

Related Questions