Повторно основывайте массив на основе 1 в c#

Необходимо смотреть на Redmine ( http://www.redmine.org/ ). Это имеет все функции, которые Вы упоминаете и т.д. Можно разместить его самостоятельно vps (я делаю).

9
задан CestLaGalere 30 September 2009 в 12:44
поделиться

7 ответов

Почему бы просто не изменить свой индекс?

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

Изменить: Вот метод расширения, который создаст новый массив с нулевым отсчетом из исходного (в основном он просто создает новый массив на один элемент меньше и копирует в этот новый массив все элементы, кроме первый элемент, который вы все равно пропускаете):

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;
}

При этом вам нужно учитывать, стоит ли штраф (пусть даже небольшой) за создание нового массива улучшения читабельности кода. Я не делаю суждения (вполне возможно, оно того стоит). Я просто убеждаюсь, что вы не запускаете этот код, если это повлияет на производительность вашего приложения.

10
ответ дан 4 December 2019 в 08:33
поделиться

Создайте оболочку для массива ExcelData с this [,] indexer и выполните там логику перебазирования. Примерно так:

class ExcelDataWrapper
{
    private object[,] _excelData;
    public ExcelDataWrapper(object[,] excelData)
    {
        _excelData = excelData;
    }
    public object this[int x, int y]
    {
        return _excelData[x+1, y+1];
    }
}
6
ответ дан 4 December 2019 в 08:33
поделиться

Так как вам нужна строка , чтобы оставаться как есть (на основе ваших комментариев), вы можете просто ввести другую переменную цикла:

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];
}
6
ответ дан 4 December 2019 в 08:33
поделиться

Почему бы не использовать:

for (int Row = 1; Row <= MaxRows; Row++) {

Или что-то мне не хватает?

РЕДАКТИРОВАТЬ: поскольку оказывается, что чего-то не хватает, я бы использовал другой счетчик (начиная с 0) для этой цели и используйте индекс строки на основе 1 для массива. Не рекомендуется использовать индекс для других целей, кроме индекса в целевом массиве.

3
ответ дан 4 December 2019 в 08:33
поделиться

Вам слишком сложно изменить счетчик цикла?

for (int Row = 1; Row <= MaxRows; Row++)

Если диапазон счетчика правильный, вам не нужно добавлять 1 к чему-либо внутри цикла, чтобы не потерять читаемость . Будьте проще.

1
ответ дан 4 December 2019 в 08:33
поделиться

Вы можете использовать сторонний компонент, совместимый с Excel, такой как SpreadsheetGear для .NET , который имеет дружественные к .NET API, включая индексирование на основе 0 для таких API, как IRange [int rowIndex , int colIndex].

Такие компоненты также будут намного быстрее, чем API Excel почти во всех случаях.

Заявление об ограничении ответственности: Я владею SpreadsheetGear LLC

-1
ответ дан 4 December 2019 в 08:33
поделиться

Я согласен с тем, что работать с массивами base-1 из .NET может быть сложно. Это также потенциально подвержено ошибкам, так как вы должны мысленно делать сдвиг каждый раз, когда используете его, а также правильно помнить, какие ситуации будут с базой 1, а какие - с базой 0.

Самый эффективный подход - это просто сделайте эти умственные сдвиги и индексируйте соответствующим образом, используя базу-1 или базу-0, если требуется.

Я лично предпочитаю преобразовывать двумерные массивы с основанием 1 в двумерные массивы с основанием 0. Это, к сожалению, требует снижения производительности при копировании массива в новый массив, так как нет никакого способа восстановить массив на месте.

Вот метод расширения, который может сделать это для 2D-массивов, возвращаемых Excel :

public static TResult[,] CloneBase0<TSource, TResult>(
    this TSource[,] sourceArray)
{
    If (sourceArray == null)
    {
        throw new ArgumentNullException(
            "The 'sourceArray' is null, which is invalid.");
    }

    int numRows = sourceArray.GetLength(0);
    int numColumns = sourceArray.GetLength(1);
    TResult[,] resultArray = new TResult[numRows, numColumns];

    int lb1 = sourceArray.GetLowerBound(0); 
    int lb2 = sourceArray.GetLowerBound(1); 

    for (int r = 0; r < numRows; r++)
    {
        for (int c = 0; c < numColumns; c++)
        {
            resultArray[r, c] = sourceArray[lb1 + r, lb2 + c];
        }
    }

    return resultArray;
}

А затем вы можете использовать это так:

object[,] array2DBase1 = (object[,]) MySheet.UsedRange.get_Value(Type.Missing);

object[,] array2DBase0 = array2DBase1.CloneBase0();

for (int row = 0; row < array2DBase0.GetLength(0); row++) 
{
    for (int column = 0; column < array2DBase0.GetLength(1); column++) 
    {
        // Your code goes here...
    }
}

Для массивов большого размера вы можете не захотеть этого делать,

0
ответ дан 4 December 2019 в 08:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: