Лучший способ переместить все элементы в списке на одну позицию в C# - PullRequest
1 голос
/ 17 июня 2020

Итак, я буду проводить измерения каждые 15 секунд, и я хочу записать измерения в список из 8 самых последних измерений.

Когда в списке 8 элементов, я хочу удалить элемент в позиции [0], переместить все остальные элементы на 1 позицию вниз (так что элемент в позиции [1] теперь имеет значение [0] et c ... а затем я хочу добавить самое последнее измерение в позицию [7].

Каков эффективный способ достижения этого?

Ответы [ 2 ]

4 голосов
/ 17 июня 2020
List<Measurement> measurements;

void AddMeasurement(Measurement measurement)
{
    if (measurements.Count == 8)
    {
        measurements.RemoveAt(0); // Indices of all remaining elements will reduce by 1
    }
    mesurements.Add(measurement);
}
0 голосов
/ 17 июня 2020

Ответ Джонатана прост и отлично подходит для небольших списков, но если данных, которые вам нужно сохранить, не 8, а гораздо больше (будущие требования), непрерывное смещение данных может оказаться дорогостоящим. Существует простой способ избежать этого, создав индивидуальную оболочку списка:

class FiniteWrapList<T>: IEnumerable<T>
{
    private readonly List<T> innerList;

    private int counter;
    private readonly int capacity;

    public static FiniteWrapList<T> CreateNew(int capacity) 
        => new FiniteWrapList<T>(capacity);

    private FiniteWrapList(int capacity)
    {
        this.capacity = capacity;
        innerList = new List<T>(capacity);
    }

    public void Add(T t)
    {
        if (counter >= capacity)
        {
            innerList[counter % capacity] = t;
        }
        else
             innerList.Add(t);

        counter = counter % (2 * capacity) + 1;
    }

    public T this[int index]
    {
        get => innerList[(counter + index) % capacity];
    }

    public IEnumerator<T> GetEnumerator()
    {
        if (counter < capacity) 
            return innerList.GetEnumerator();

        return GetWrappedListEnumerator();

        IEnumerator<T> GetWrappedListEnumerator()
        {
            for (var i = 0; i < capacity; i++)
                yield return innerList[(counter + i) % capacity];
        }
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

Таким образом вы избежите беспорядка с перемещением данных внутри списка. Вы просто создаете интеллектуальный индексатор и используете единый список, в котором просто перезаписываете старые данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...