在RX网站的complex event processing workshop中,使用缓冲区完成了挑战5。我有一个使用LINQ点或lamba表示法的解决方案。出于兴趣,我想将其转换为LINQ语言集成查询表示法。
挑战和我的代码如下。由于某些原因result2
无法正常工作,它会使UI无响应并且输出看起来被截断。这是一个时髦的东西,是我的查询,你能解决它吗?
挑战(下载here)
IObservable<object> Query(IObservable<StockQuote> quotes)
{
// TODO: Change the query below to compute the average high and average low over
// the past five trading days as well as the current close and date.
// HINT: Try using Buffer.
return from quote in quotes
where quote.Symbol == "MSFT"
select new { quote.Close, quote.Date };
}
我的解决方案
IObservable<object> Query(IObservable<StockQuote> quotes)
{
// TODO: Change the query below to compute the average high and average low over
// the past five trading days as well as the current close and date.
// HINT: Try using Buffer.
var result1 = quotes.Where(qt => qt.Symbol == "MSFT").Buffer(5, 1).Select(quoteList =>
{
var avg = quoteList.Average(qt => qt.Close);
return new { avg, quoteList.Last().Close, quoteList.Last().Date };
});
var result2 = from quote in quotes
where quote.Symbol == "MSFT"
from quoteList in quotes.Buffer(5, 1)
let avg = quoteList.Average(qt => qt.Close)
select new { avg, quoteList.Last().Close, quoteList.Last().Date };
return result2;
}
答案 0 :(得分:1)
两种解决方案都多次订阅引号(甚至超过两次 - 记住多个子句会导致引擎盖下的SelectMany调用),所以那里已经出现了问题:-)。再试一次。
答案 1 :(得分:0)
我认为查询看起来应该更像这样:
var result =
from quote in quotes
where quote.Symbol == "MSFT"
from quoteList in quotes.Buffer(5, 1)
let avgHigh = quoteList.Average(qt => qt.High)
let avgLow = quoteList.Average(qt => qt.Low)
select new { avgHigh, avgLow, quote.Close, quote.Date };
但这与你的只有很小的区别 - 只有当quoteList.Last()
做&amp;时才需要quote
。问题是High
&amp;的平均值。 Low
,而不是Close
。
据我所知,问题在于图表而不是Rx组件。我认为图表经常重绘,以至于它正在阻塞。
答案 2 :(得分:0)
问题要求同时绘制两个图形(当前,平均)。
我不相信可以使用绑定monad(SelectMany
)来独立地组成问题所指定的那两个流的最新值。
quotes.Buffer
向下的理解将与缓冲流的速率绑定。
可替换地:
quotes = quotes.Publish().RefCount();
return Observable.CombineLatest
(
first: quotes,
second: quotes.Buffer(5, 1).Select(
buffer => new { High = buffer.Average(q => q.High), Low = buffer.Average(q => q.Low) }),
resultSelector: (l, r) => new { l.Close, l.Date, r.High, r.Low }
);
以与源相同的速率移动,从而产生平滑的图形。