替换列表中的最旧值?

时间:2016-05-02 00:35:11

标签: c# queue

我正在创建一个应用程序,其作用是生成两个列表并按需显示它们。以及每秒更新值。

我需要以这样的方式更新列表,以便首先替换列表中最旧的值。我该怎么办?以下是我当前状态的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Data_Collector
{
    //What is needed?
    //Need to generate a list of both metric values, and imperial values.
    //Need to be able to display a list 

    public class IMeasuringDevice_Helper
    {
        private int limit; //Limits the list size.
        private float RNDouble;

        public void MetricValueGenerator()
        {

            limit = limit + 1;
            Console.WriteLine("Limit Level = " + limit);


            if (limit <= 10)
            {
                List<float> MetricValueGenerated = new List<float>();

                Random rnd = new Random();
                float rndINT = rnd.Next(1, 10);
                RNDouble = rndINT / 10;
                Console.WriteLine(RNDouble);
                MetricValueGenerated.Add(RNDouble);
            }
            else
            {
                Console.WriteLine("limit reached");
            }

        }

        public void ImperialValueGenerator()
        {
            //TODO
        }

    }
}

2 个答案:

答案 0 :(得分:1)

此处需要Queue,但您需要对其进行扩展。默认的C#Queue是First-In,First-Out(完全是您想要的语义),但不会订阅限制代码当前处理它们的方式。如果充满,它只会增长一个增长因素。

因此,您需要扩展Queue对象并覆盖Enqueue方法以执行您想要的操作。它可能看起来有点像这样:

public class BoundedQueue<T> : Queue<T>
{
   private readonly int _bound;

   public BoundedQueue(int bound)
   {
       _bound = bound;
   }

   public new void Enqueue(T item)
   {
       if(Count >= _bound)
       {
            throw new IndexOutOfRangeException("limit reached");
            // If simply throwing an exception isn't cool, you can also do the following to pop off the oldest item:
            // base.Dequeue();
       }
       base.Enqueue(item);
   }
}

唯一需要注意的是当你把它变成其他类型的对象进行显示时,你可能会按照你期望的相反顺序看到它,因为最旧的项目将位于队列的“顶部”。您只需调用适用于大多数支持LINQ的对象的Reverse()方法即可对其进行排序。

答案 1 :(得分:0)

如果您不想像@YYY所建议的那样进行任何类扩展,请将List替换为Queue,将.add()替换为.Enqueue(),而不是oldestValue = yourList[oldestIndex]使用oldestValue = yourQueue.Dequeue()

除了你的问题,你的变量应该以小写字母开头,RNDouble = rndINT / 10;大部分时间都会以= 0结束,因为你应该除以10.0而不是10。

好的,所以我很无聊......(我也不会采用这种方法,但是我猜你正在学习并且没有被教过关于队列的知识,所以这个可能有助于列表):

public class MeasuringDevice_Helper
{
    private const int LIMIT = 10;   // This is a constant value, so should be defined IN_CAPS in class definition
    List<double> metricValues = new List<double>(LIMIT);    // This needs to be at class level so it doesn't get lost
    Random rnd = new Random();  // This is used frequently so define at class level

    public void GenerateMetricValue()  // This is now named like the action it performs
    {
        Console.WriteLine("Current metric values = " + metricValues.Count);

        if (metricValues.Count < LIMIT)     // This should just be < not <=
        {
            float rndInt = rnd.Next(1, 10);
            double rndDouble = rndInt / 10.0;   // An Int divided by Int will = Int
            Console.WriteLine("Added " + rndDouble);
            metricValues.Add(rndDouble);
        }
        else
        {
            Console.WriteLine("limit reached");
        }
    }

    public double PopOldestMetricValue()
    {
        double value = metricValues[0];
        metricValues.RemoveAt(0);
        return value;
    }
}
相关问题