0

I have the following expression which groups stock quotes by symbol and returns an observable sequence of PriceChange objects reflecting the difference in price between two ticks of the same stock symbol:

return from q in quotes
       group q by q.Symbol into g
       from b in g.Buffer(2, 1)
       select new PriceChange() { Symbol = b[0].Symbol, Change = (b[1].Price - b[0].Price) / b[0].Price };

What I am trying to do is write the equivalent expression using LINQ fluent expressions. The closest I have come is this:

return quotes.GroupBy(q => q.Symbol)
             .Select(g => g.ToList()
                 .SelectMany(l => l)
                 .Buffer(2, 1)
                 .Do(b => Console.WriteLine(b[0].Symbol + "-" + b[1].Symbol))
                 .Select(b => new PriceChange())
              );

However this does not compile as the return type of that expression is IObservable<IObservable<PriceChange>> when what I need is just a IObservable<PriceChange>

If I try adding a SelectMany clause like this:

return quotes.GroupBy(q => q.Symbol)
             .Select(g => g.ToList()
                 .SelectMany(l => l)
                 .Buffer(2, 1)
                 .Do(b => Console.WriteLine(b[0].Symbol + "-" + b[1].Symbol))
                 .Select(b => new PriceChange())
              ).SelectMany(o => o);

it compiles but never produces any output.

What am I doing wrong here? How can I express this correctly using the fluent LINQ operators?

mclaassen
  • 5,018
  • 4
  • 30
  • 52
  • 1
    Try to use LINQpad to convert LINQ to Lambda expressions see: http://stackoverflow.com/questions/1524813/convert-this-linq-expression-into-lambda – Martijn van Put Jun 04 '14 at 21:07

1 Answers1

1

I think you need:

return quotes
    .GroupBy(q => q.Symbol)
    .SelectMany(g => g.Buffer(2, 1).Select(b => new PriceChange {
        Symbol = b[0].Symbol,
        Change = (b[1].Price - b[0].Price) / b[0].Price
     })
    );
Lee
  • 142,018
  • 20
  • 234
  • 287