3 回答
TA贡献1794条经验 获得超8个赞
小修正 - 当前实现的时间复杂度是 O(N*M),你能得到的最好的是 O(N+M)。
问题是如何有效地关联这两个集合。在 LINQ 中,这是通过连接实现的,对于这种一对多类型的关联 -组连接。标准的等价物||将是两个组连接(匹配集)结果的联合。
谈到可读性、LINQ 和连接,最好的方法是使用 LINQ查询语法(有些人也称它为理解语法是有原因的)。
所以有问题的查询可以有效地(并且希望可读)重写如下:
var invalidQuantityItems =
from returnItem in message.ItemsForReturn
join orderItem in message.OrderItems on returnItem.ItemNumber equals orderItem.ItemNumber
into matchingOrderItems1
join orderItem in message.OrderItems on returnItem.OrderItemId equals orderItem.OrderItemId
into matchingOrderItems2
let matchingOrderItemQuantity = matchingOrderItems1.Union(matchingOrderItems2)
.Sum(orderItem => orderItem.Quantity)
where matchingOrderItemQuantity < returnItem.Quantity
select returnItem;
TA贡献1846条经验 获得超7个赞
我认为字典方法是最好的方法。
关于可读性,我认为这应该不会太差:
var quantityByItemNumber = message.OrderItems.
Where(i => i.ItemNumber != null).
ToDictionary(
i => i.ItemNumber,
i => i.Quantity);
var quantityByOrderItemId = message.OrderItems.ToDictionary(
i => i.OrderItemId,
i => i.Quantity);
var invalidQuantityItems = message.ItemsForReturn.Where(returnItem =>
{
int matchingOrderItemQuantity;
var isNumberMatch = returnItem.ItemNumber != null) &&
quantityByItemNumber.TryGetValue(returnItem.ItemNumber, out matchingOrderItemQuantity);
if (!isNumberMatch)
quantityByOrderItemId.TryGetValue(returnItem.OrderItemId, out matchingOrderItemQuantity)
return matchingOrderItemQuantity < returnItem.Quantity;
});
事实上,我认为这更具可读性,因为它不会错误地假装有不止一个匹配OrderItem,必须对哪些数量求和。
TA贡献1876条经验 获得超7个赞
就优化多个条件而言:
始终将最有可能结束评估的条件放在首位(您必须根据现有数据或您对系统的了解来确定这一点)。
如果一种情况比另一种情况更频繁地发生的可能性不大,那么我们可以考虑评估本身。例如,如果
int
比较比比较快string
,则将int
比较放在第一位。
此外,您的代码不需要单独的行来获取Sum
; 你可以用同一个表达式来做:
var invalidQuantityItems = message.ItemsForReturn.Where(returnItem =>
message.OrderItems
.Where(orderItem =>
orderItem.OrderItemId == returnItem.OrderItemId ||
orderItem.ItemNumber.Equals(returnItem.ItemNumber))
.Sum(orderItem => orderItem.Quantity) < returnItem.Quantity);
- 3 回答
- 0 关注
- 129 浏览
添加回答
举报