Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rebase a 1-based array in c#

Tags:

c#

.net

excel

I have an array in c# that is 1-based (generated from a call to get_Value for an Excel Range I get a 2D array for example

object[,] ExcelData = (object[,]) MySheet.UsedRange.get_Value(Excel.XlRangeValueDataType.xlRangeValueDefault);

this appears as an array for example ExcelData[1..20,1..5]

is there any way to tell the compiler to rebase this so that I do not need to add 1 to loop counters the whole time?

List<string> RowHeadings = new List<string>();
string [,] Results = new string[MaxRows, 1]
for (int Row = 0; Row < MaxRows; Row++) {
    if (ExcelData[Row+1, 1] != null)
        RowHeadings.Add(ExcelData[Row+1, 1]);
        ...
        ...
        Results[Row, 0] = ExcelData[Row+1, 1];
        & other stuff in here that requires a 0-based Row
}

It makes things less readable since when creating an array for writing the array will be zero based.

like image 408
CestLaGalere Avatar asked Sep 30 '09 12:09

CestLaGalere


3 Answers

Why not just change your index?

List<string> RowHeadings = new List<string>();
for (int Row = 1; Row <= MaxRows; Row++) {
    if (ExcelData[Row, 1] != null)
        RowHeadings.Add(ExcelData[Row, 1]);
}

Edit: Here is an extension method that would create a new, zero-based array from your original one (basically it just creates a new array that is one element smaller and copies to that new array all elements but the first element that you are currently skipping anyhow):

public static T[] ToZeroBasedArray<T>(this T[] array)
{
    int len = array.Length - 1;
    T[] newArray = new T[len];
    Array.Copy(array, 1, newArray, 0, len);
    return newArray;
}

That being said you need to consider if the penalty (however slight) of creating a new array is worth improving the readability of the code. I am not making a judgment (it very well may be worth it) I am just making sure you don't run with this code if it will hurt the performance of your application.

like image 74
Andrew Hare Avatar answered Oct 04 '22 02:10

Andrew Hare


Create a wrapper for the ExcelData array with a this[,] indexer and do rebasing logic there. Something like:

class ExcelDataWrapper
{
    private object[,] _excelData;
    public ExcelDataWrapper(object[,] excelData)
    {
        _excelData = excelData;
    }
    public object this[int x, int y]
    {
        return _excelData[x+1, y+1];
    }
}
like image 40
Daren Thomas Avatar answered Oct 04 '22 02:10

Daren Thomas


Since you need Row to remain as-is (based on your comments), you could just introduce another loop variable:

List<string> RowHeadings = new List<string>();
string [,] Results = new string[MaxRows, 1]
for (int Row = 0, SrcRow = 1; SrcRow <= MaxRows; Row++, SrcRow++) {
    if (ExcelData[SrcRow, 1] != null)
        RowHeadings.Add(ExcelData[SrcRow, 1]);
        ...
        ...
        Results[Row, 0] = ExcelData[SrcRow, 1];
}
like image 45
Jason Avatar answered Oct 04 '22 00:10

Jason