#!markdown # Simple Moving Average and `IAsyncEnumerable` Khalid said:

Hey @andrewlocknet! It would be cool to see your Simple Moving Average take in a IAsyncEnumerable and recalculate the average as new input comes in.https://t.co/NIw8Ow5PA5

— Khalid 🪀 (@buhakmeh) May 7, 2021
I decided to look into it! First step, we have the existing Simple Moving Average calculator from [my post](https://andrewlock.net/creating-a-simple-moving-average-calculator-in-csharp-1-a-simple-moving-average-calculator/). #!csharp public class SimpleMovingAverage { private readonly int _k; private readonly int[] _values; private int _index = 0; private int _sum = 0; public SimpleMovingAverage(int k) { if (k <= 0) throw new ArgumentOutOfRangeException(nameof(k), "Must be greater than 0"); _k = k; _values = new int[k]; } public double Update(int nextInput) { _sum = _sum - _values[_index] + nextInput; _values[_index] = nextInput; _index = (_index + 1) % _k; return ((double) _sum) / _k; } } #!markdown Khalid said he wanted to take an `IAsyncEnumerable` of inputs, and retrieve an `IAsyncEnumerable` of outputs. This is essentially just a mapping from one `IAsyncEnumerable` to another. There's a few ways we could do that, but to keep everything encapsulated, I created an `SmaConverter` class that wraps the `SimpleMovingAverage` to do the conversion: #!csharp public class SmaConverter { private readonly SimpleMovingAverage _sma = new(k: 3); public async IAsyncEnumerable GetAverage(IAsyncEnumerable inputs) { await foreach (int input in inputs) yield return _sma.Update(input); } } #!markdown That's all we need to do the conversion, so now lets create a class to get our `IAsyncEnumerable` input: #!csharp async IAsyncEnumerable GetInputs() { await Task.Yield(); yield return 1; yield return 2; yield return 3; yield return 2; yield return 2; yield return 1; yield return 1; yield return 3; yield return 3; yield return 3; } #!markdown And finally, lets put it all together #!csharp var converter = new SmaConverter(); var values = GetValues(); await foreach(var average in converter.GetAverage(values)) { Console.WriteLine(\$"Next average is {average:0.00}"); } #!markdown And voila!