Tutorial :Multidimensional Data Structure in C#



Question:

I want to build a data structure which is basically a matrix of strings with the following.

  1. A growable no of rows
  2. A FIXED no of columns

I want to be able to get at whatever is in a particular row or column via a method call that takes the an integer row no and an int col number as an argument. In addition I want to be able to set the value of a column which using the row and col no.

I could do this myself but am open to seeing what other people might do...

EDIT Sorry the column list will be fixed, my mistake :-(


Solution:1

The DataTable and the DataSet (basically a collection of data tables) would work fine for what you are looking for.

You could then access your data (once you set up the columns and added your rows of data) via the following syntax:

datatable.rows(index)("ColumnName")  

or

datatable.rows(rowindex)(columnindex)  


Solution:2

Sounds to me like a data table would be the easiest opion.


Solution:3

If you need more than two dimensions, or want a more generic solution, you could possibly make it work with a List<List<T>>, nested as deeply as required, and wrapped in a custom type if you need more specific functionality or want simpler method calls.


Solution:4

If I wanted/needed to roll my own (say I didn't want to deal with what DataTable/DataSet) then I'd write something around a List<List<T>> (or List<List<object>>) as a list of rows then columns with logic to keep the lists rectangular.

  • AddRow() would add a new outer list entry.
  • AddColumn() would add a new item to all lists in the inner list.
  • this[int row, int col] would access this._Data[row][col].

Something like that.

Switch to a Dictionary<K, List<V>> if I wanted named columns (then the lists contain row data for that column).


Solution:5

If you want it to be expandable in both directions then a DataTable isn't the best of choices.

For the interface, you can use an indexer property:

class Foo   {         public string this[int x, int y]      {          get { return GetData(x,y); }      }  }  

For the backend Storage, the best option depends a bit on expected usage, ie will there be lots of empty cells. You could define a

struct Index { public readonly int X, Y; }  

and override the Equals() and GetHashCode() members. There have been several questions about this on SO recently.

After that, use a Dictionary < Index, string>

You'd still have to manage Row and Column limits, and maybe intercept getting of empty cells.


Solution:6

How about basing something on Dictionary<System.Drawing.Point, string>? So that you can write;

stringGrid.Add(new Point(3,4), "Hello, World!");  

Create a class containing such a dictionary and then you get what you're looking for, almost for free. Something like (untested)

class StringGrid  {      Dictionary<System.Drawing.Point, string> grid;        public StringGrid      {          this.grid = new Dictionary<System.Drawing.Point, string>();      }        public string Get(int x, int y)      {          string result = null;          grid.TryGetValue(new Point(x,y), out result);          return result;      }        public void Set(int x, int y, string content)      {          var pos = new Point(x,y);          if (grid.ContainsKey(pos))          {              if (content == null)              {                  // no content, so just clear the cell.                  grid.remove(pos);              }              else              {                  // add new content                  grid[pos].Value = content;              }            }           else if (content != null)          {              // new non-null content              grid.add(pos, content);          }      }  }  

EDIT: Also, if you want to get really flash;

  • replace the dictionary with a SortedList<,>
  • replace System.Drawing.Point with your own struct which implements IComparable

This way, the list would be internally ordered by row, then by column, making a simple foreach loop sufficient to iterate through all the values in the first row, then the values in the second, and so on. Allows you to convert to and `IEnumerable`` -- or a collection of rows.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »