C# - 移动平均线

C# - Moving average

我是 C# 的新手,似乎找不到适合我的东西。 我需要从可以成功收集的串口获取数据。每次单击按钮时,都会显示数据。 这个数据需要放在一个数组中,我想在这个数组上计算移动平均值。

解决这个问题的最佳方法是什么?

private void btnRead_Click(object sender, EventArgs e)
{            
    // Filtering incoming data from string to double
    string inComingData = serialPort.ReadLine();
    int charLoc = 0;
    int serialCharLoc = inComingData.IndexOf("N");

    while(!(inComingData.Contains("N")) && !(charLoc == serialCharLoc)) 
    {
        inComingData = serialPort.ReadLine();              
    }
    rtbIncoming.Text = inComingData;
    string [] usableData = inComingData.Split(' ');
    string correctData = usableData[1];
    tbData.Text = correctData;
    serialPort.DiscardInBuffer();

这是我现在从串口获取过滤数据的代码。

因此可以跟踪您拥有的每个数据:

public class MyClass // Don't know the name of your class 
{
   private readonly List<double> _values;
   
   public MyClass() 
   {
      _values = new List<double>();
   }

   // ...

   private void btnRead_Click(object sender, EventArgs e)
{            
    // Filtering incoming data from string to double
    string inComingData = serialPort.ReadLine();
    int charLoc = 0;
    int serialCharLoc = inComingData.IndexOf("N");

    while(!(inComingData.Contains("N")) && !(charLoc == serialCharLoc)) 
    {
        inComingData = serialPort.ReadLine();              
    }
    rtbIncoming.Text = inComingData;
    string [] usableData = inComingData.Split(' ');
    string correctData = usableData[1];
    tbData.Text = correctData;
    
    _values.Add(double.Parse(correctDate) // Only use "double.Parse" if you're sure it will be a double. If not use "double.TryParse".
    var average = _values.Average() // This will give you the average.
    var average2 = _values.TakeLast(x).Average() // This will give you the average for the last x items.
    
    serialPort.DiscardInBuffer();
}

如果您的元素数量非常多(我认为情况并非如此,因为只有在用户单击时才会添加新元素)性能不会很好,因此您将不得不做一些改变如建议,如果评论保留一个累加器。

编辑:TakeLast 似乎介绍得更多 recently than I thought 这是您可以使用的自定义实现:

public static class LinqHelper
{
    public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int count)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }


        int from = count < 0 ? source.Count() : count > source.Count() ? 0 : source.Count() - count;
        for (int i = from; i < source.Count(); i++)
        {
            yield return source.ElementAt(i);
        }

    }
}

我试图尊重与现有行为相同的行为,但我认为实现仍然很幼稚,所以它在某些情况下可能不起作用。