简体   繁体   English

在 C# 中将列表中的所有项目移动一个 position 的最佳方法

[英]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.因此,我将每 15 秒进行一次测量,并且我想将测量结果记录在 8 个最近测量值的列表中。

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].当列表有 8 个项目时,我想删除 position [0] 处的项目,将所有其他项目下移 1 position (所以 position [1] 处的项目是最最近测量到 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. Johnathan 的回答很简单,非常适合小型列表,但如果您需要存储的数据不是 8 个,而是更多(未来的要求),那么连续移动数据可能会变得很昂贵。 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.您只需创建一个智能索引器并使用一个列表即可覆盖旧数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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