Introduction
The techniques presented in this article have many useful applications. For example, in one of my previous articles, I used a List<double>
to store and manipulate all the matrices.
When you want to store some tabular data, you usually think of a two dimensional data structure. However, in this article we will see that on many occasions storing the data itself in a single dimensional way will make internal tasks simpler. The single dimensional source does not stop us from presenting or using the data in two dimensional way. So we can, at the same time, perform two dimensional operations on it.
Uses
One obvious question that comes to your mind is why store two dimensional data in a single dimensional data source. Here is a list of why one would want to do so:
- The number of rows and columns is not known in advance and will only be known when needed.
- The data is bound to some inherently single dimensional source at the back end but needs to be accessed in two dimensional way at run-time.
- The data can be accessed in single and/or two dimensional manner at the same time.
- The number of rows and columns change dynamically.
Two Dimensional Operations on Single Dimensional Data Structures
In the following sections, we shall see how to perform different two dimensional operations on a single dimensional list.
Getting Row Number of an Item
Given the column count and index of an item in the array, the row number can be obtained by calculating the quotient using integral division like this:
int [] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int columnCount = 3;
for (int i=0; i < numbers.Length; i++)
{
int rowNumberOfItem = i/columnCount;
}
Getting Column Number
Given the index of an item in the array, the column number can be obtained by calculating the remainder using integral division like this:
int [] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int columnCount = 3;
for (int i=0; i < numbers.Length; i++)
{
int columnNumberOfItem = i%columnCount;
}
Swapping Rows and Columns
Following is one of the possible solutions:
int [] original = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int [] transpose = new int[original.Length];
int columns = 3;
int rows = original.Length/columns;
for (int i = 0; i < columns; i++)
{
for (int j = 0; j < rows; j++)
{
transpose[i * rows + j] = original[j * columns + i];
}
}
Accessing all the Column Values at a Given Index using a Loop
This task can be carried out using something like this:
int [] original = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int columns = 3;
int rows = original.Length/columns;
int [] columnValues = new int [rows];
int index = 2;
for (int i = 0; i < rows; i++)
{
columnValues[i] = original[i*columns + index];
}
Accessing all the Row Values at a Given Index using a Loop
This task can be carried out using something like this:
int [] original = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int columns = 3;
int rows = original.Length/columns;
int [] rowValues = new int [columns];
int index = 2;
for (int i = 0; i < columns; i++)
{
rowValues[i] = original[index*columns + i];
}
Conclusion
We provided a quick overview of how a single dimensional array can be treated as a two dimensional data structure. We also noted how and when this approach can be useful.
For a much more elaborate use of this technique, refer to the Matrix implementation of the sample project provided with my previous article: Building a General Purpose Interpreter, Math Engine and Parser in C#, where all the matrix support is built using the simple techniques presented here.
Please let me know if you find anything unclear or missing.