简体   繁体   中英

Best way to move all items in a list by one position in C#

So I will be taking a measurement every 15 seconds and I want to record the measurements in a list of the 8 most recent measurements.

When the list has 8 items, I want to remove the item at position [0], move all other items down 1 position (so the item at position [1] is now [0] etc. and then I want to add the most recent measurement to position [7].

What is an effiecient way of achieving this?

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

Johnathan's answer is simple and great for small lists, but if the data you need to store is not 8, but much more (future requirements), continuously shifting data can get to be expensive. There is an easy way to avoid this creating a custom made list wrapper:

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

This way you avoid all the mess of shifting data inside a list. You simply create a smart indexer and use a single list where you just overwrite old data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM