[英]How to get the sum of the volume of highest and lowest priced items in linq
我试图写的实际查询比标题所暗示的要复杂一些。 我有一个这样的订单列表: List<Order>
,订单如下:
public class Order
{
private StockCodes _stockCode;
private bool _bidSide;
private int _volume;
private decimal _price;
}
我需要在给定特定股票代码的情况下公布最佳买入价和成交量以及最佳卖出价和成交量。 最佳报价定义为bidSide为true的最高价格。 最佳卖价定义为bidSide为false的最低价格。
例如,给出股票代码“ABC”的以下数据:
{ bidSide: true, volume: 25, price: 25 }
{ bidSide: true, volume: 25, price: 25 }
{ bidSide: true, volume: 25, price: 5 }
{ bidSide: false, volume: 100, price: 1 }
{ bidSide: false, volume: 50, price: 2}
{ bidSide: false, volume: 75, price: 8 }
最佳出价:价格25,成交量50(因为最高价格有2个订单)最畅销:价格1,成交量100(因为最低价格只有1个订单)
最后,我需要考虑什么时候没有买入或卖出订单。 效率是高优先级,所以如果我能够在一个首选的linq语句中这样做。
要有效地执行此操作,您实际上只想迭代数据一次。 不幸的是,这使用LINQ实现真正的痛苦,因为还有很多工作要做。
我个人建议你不要用LINQ做这个 - 你可以用Aggregate
实现它,但它不会非常令人愉快。 虽然简单的foreach
循环并不算太糟糕。 就像是:
int buyVolume = -1;
int sellVolume = -1;
decimal buyPrice = decimal.MinValue;
decimal sellPrice = decimal.MaxValue;
foreach (var order in orders)
{
if (order.bidSide)
{
if (order.Price > buyPrice)
{
buyPrice = order.Price;
buyVolume = order.Volume;
}
else if (order.Price == buyPrice)
{
buyVolume += order.Volume;
}
}
else
{
if (order.Price < sellPrice)
{
sellPrice = order.Price;
sellVolume = order.Volume;
}
else if (order.Price == sellPrice)
{
sellVolume += order.Volume;
}
}
}
// Check sellVolume == -1 to verify whether we've seen any sale orders
// Check buyVolume == -1 to verify whether we've seen any buy orders
// Use buyPrice/buyVolume and sellPrice/sellVolume otherwise
在LINQ中尽可能高效地执行它实际上意味着将循环中的所有逻辑放入一个函数以传递到Aggregate
- 并且您可能想要创建一个自定义值类型来保存四个值,以避免创建比你需要。 这可能有点矫枉过正,但你确实说过你希望它尽可能高效......
HIGHEST = orders.Max(x => x.bidSide ? x.price : (decimal?)null) ?? 0M
类似于LOWEST。
不幸的是,Linq2SQL不会将其转换为有效的查询。 它将在一个查询中执行,但每次Max操作将扫描一次数据(在您的情况下,两次:HIGHEST和LOWEST)。 在原始SQL中,您可以在一次传递数据时执行此操作。
这可以做LINQ明智的......
var bids = (from o in orders
where o.StockCode == "ABC" && o.BidSide == true
group o by o.Price)
.OrderByDescending(g => g.Key)
.FirstOrDefault();
var bidVolume = bids != null ? new Order { Price = bids.Key, Volume = bids.Sum(g => g.Volume) } : null;
var sells = (from o in orders
where o.StockCode == "ABC" && o.BidSide == false
group o by o.Price)
.OrderBy(g => g.Key)
.FirstOrDefault();
var sellVolume = sells != null ? new Order { Price = sells.Key, Volume = sells.Sum(g => g.Volume) } : null;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.