Manuel
Manuel

Reputation: 11479

How to get values from dictionary with composite keys?

My program has a grid of cells and I want to be able to efficiently query either by row or by column number. What kind of structure should I use to do this?

For example I'd like to have the following methods:

CellsCollection.GetCell(Int32 row, Int32 column)
CellsCollection.GetAllCellsInRow(Int32 row)
CellsCollection.GetAllCellsInColumn(Int32 column)

My first try was to create a struct with two fields (row and column) and then a dictionary with a composite key of the struct: Dictionary<struct, cell>.

CellsCollection.GetCell(Int32 row, Int32 column) is no problem because I'd be querying the dictionary by the composite key.

The other two (get cells in row/column) present the problem because if I do:

dictionary.Where(keyPair=>keyPair.Key.Row == row).Select(keyPair=>keyPair.Values.Cell)

Then the dictionary key becomes moot and the program has to go through every key in the dictionary.

I thought of a nested dictionary (the outer one with a row key and the inner one with a column key) but I that would only help if I'm querying by row, not by column.

How would you overcome this?

Upvotes: 0

Views: 1004

Answers (1)

Colin Mackay
Colin Mackay

Reputation: 19185

A dictionary is great if you have gaps in your indexes. If you have a grid of cells then I'm guessing then that is not the case (unless you have lots of empty cells).

So, why not have an 2-dimensional array? e.g.

int[,] cells = new int[maxRow,maxColumn];

That way if you want to query a specific cell you just do

int cellValue = cells[row,column]

or

public int GetCell(Int32 row, Int32 column)
{
    return cells[row, column]
}

If you want to get everything in a row:

for(int col = 0; col < maxColumn; col++)
    int cellValue = cells[row, col];

or

 public IEnumerable<int> GetAllCellsInRow(Int32 row)
 {
    for(int col = 0; col < maxColumn; col++)
        yeldReturn cells[row, col];
 }

And for everything in a column similarly

for(int row = 0; row < maxRow; row++)
    int cellValue = cells[row, column];

or

public IEnumerable<int> GetAllCellsInColumn(Int32 column)
{
    for(int row = 0; row < maxRow; row++)
        yield return cells[row, column];
}

Upvotes: 3

Related Questions