Как эффективно изменить размер массива значений без использования бокса внутри словаря <string, float []> - PullRequest
0 голосов
/ 18 января 2011

В приведенном ниже коде страницы определены как

 public SortedDictionary<DateTime, float[]> Pages { get; set; }

Я пытаюсь динамически увеличить размер этого массива. Кто-нибудь может подсказать, как увеличить размер самого внутреннего поплавка []?

 var tt = currentContainer.Pages[dateTime];
 Array.Resize<float>(ref tt, currentContainer.Pages.Count + 1);

Fail 1

Я попробовал следующий код и вывел исключение индекса из диапазона

    SortedDictionary<DateTime, float[]> Pages = new SortedDictionary<DateTime,float[]>();
    float[] xx = new float[1];
    xx[0] = 1;
    DateTime tempTime = DateTime.UtcNow;
    Pages.Add(tempTime, xx);
    var tt = Pages[tempTime];
    Array.Resize<float>(ref tt, Pages.Count + 1);
    Pages[tempTime][1] = 2;

Fail 2

Следующее дает ошибку времени компиляции (свойство, индекс или динамический член не могут использоваться в качестве значения ссылки)

    SortedDictionary<DateTime, float[]> Pages = new SortedDictionary<DateTime,float[]>();
    float[] xx = new float[1];
    xx[0] = 1;
    DateTime tempTime = DateTime.UtcNow;
    Pages.Add(tempTime, xx);
    var tt = Pages[tempTime];
    // The line below is different from Fail 1 above ... compile time error
    Array.Resize<float>(ref Pages[tempTime], Pages.Count + 1);
    Pages[tempTime][1] = 2;

Вопрос

Какой самый эффективный ответ для изменения размера этого массива?

Изменится ли ответ, если вероятно, что окончательный размер будет 100-200 поплавков или 700-900 поплавков?

Что если я изменю размер своего распределения с +1 на +128? .. или больше?

Ответы [ 5 ]

7 голосов
/ 18 января 2011

Использование List<T>,

Пример,

SortedDictionary<DateTime, List<float>> data;

data = new SortedDictionary<DateTime, List<float>>();

data.Add(DateTime.Now, new List<float>() { 11.4f, 322.3f, 33.5f });

РЕДАКТИРОВАТЬ:

Как получить / установить значения из списка?

List<float> a = new List<float>()
{
  10.2f,20.3f
};

float v1 = a[0];
float v2 = a[1];

Console.WriteLine("{0} {1}", v1, v2);

a[0] = 90.40f;
Console.WriteLine("{0} {1}", a[0],a[1]);
3 голосов
/ 18 января 2011

Во-первых, рассмотрите возможность использования Dictionary<DateTime, List<Float>> вместо массива. Поскольку все ваши примеры кода включали увеличение размера массива на 1, для меня это означает, что вы собираетесь изменить размеры массивов много раз, чтобы получить их окончательный размер. Если это так, то выбор контейнера, который может расширяться сам по себе и может делать это эффективно, будет лучше.

Во-вторых, все ваши примеры используют длины массивов, на один больше, чем количество элементов в словаре. Это необычные отношения, вы уверены, что Dictionary<DateTime, (some group of floats)> - это правильный контейнер?

Тем не менее, вот как изменить размер массива в Словаре.

SortedDictionary<DateTime, float[]> Pages = new SortedDictionary<DateTime,float[]>();
DateTime date = DateTime.UtcNow;

float[] arr = Pages[date];
Array.Resize<float>(ref arr, arr.Length + 1);
Pages[date] = arr; // [] overwrites the old value, unlike Add().
1 голос
/ 18 января 2011

Я бы использовал Список, как предложено в других ответах.Причина, по которой вы не можете изменить массив с помощью Array.Resize(), заключается в том, что он копирует массив в новый массив, для которого он возвращает ссылку для (выходные данные рефлектора ниже) - поэтому, если вы не назначите новое значение для Pages[tempTime]тебе не повезло.

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void Resize<T>(ref T[] array, int newSize)
{
    if (newSize < 0)
    {
        throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
    }
    T[] sourceArray = array;
    if (sourceArray == null)
    {
        array = new T[newSize];
    }
    else if (sourceArray.Length != newSize)
    {
        T[] destinationArray = new T[newSize];
        Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length);
        array = destinationArray;
    }
}
1 голос
/ 18 января 2011

вместо

public SortedDictionary Pages {get; задавать; },

вы можете использовать

public SortedDictionary > Pages {get; задавать; },

чтобы вам не пришлось изменять размер, и если вы все еще хотите обращаться к нему как к массиву, вы всегда можете использовать ToArray () класса List.

Надеюсь, это поможет

1 голос
/ 18 января 2011

Array.Resize (ref tt, Pages.Count + 1);Pages [tempTime] = tt;

...