c# - 优化具有多个条件的嵌套 where 子句的最佳方法是什么?

标签 c# .net algorithm performance

我正在尝试查找 ReturnItems 的列表退回的单个商品的数量超过该商品的原始订购数量。所以这里有 2 个不同的对象列表 - IEnumerable<ReturnItem>IEnumerable<OrderItem> .问题是根据返回的来源(我们的工作流程中有多个地方可以返回)ItemNumber在给定的 ReturnItem可能为空。在这种情况下,我们需要依赖 ReturnItem.OrderItemId将其与 OrderItem 匹配.

我已经使用 LINQ 解决了这个问题,但是它需要一个嵌套的 for 循环(在幕后)所以我尽量避免这种情况同时保持可读性。换句话说,我想避免运行时间O(N^2) 并寻找 O(N) 或更好但又一次,同时保持可读性(我知道我在这里要求很多但我想我会看看是否有人有创造性的解决方案)。我创建了一个解决方案,其中我有两个用于订单项的字典。其中一个,键是项目编号,另一个键是订单项目 ID。这有效并解决了性能问题,但我完全失去了可读性。

这是我的原始 LINQ 语句:

// ItemsForReturn = IEnumerable<ReturnItem>
// OrderItems = IEnumerable<OrderItem>

var invalidQuantityItems = message.ItemsForReturn.Where(returnItem =>
{
    var matchingOrderItemQuantity = message.OrderItems
        .Where(orderItem => orderItem.ItemNumber.Equals(returnItem.ItemNumber) || orderItem.OrderItemId == returnItem.OrderItemId)
        .Sum(orderItem => orderItem.Quantity);

    return matchingOrderItemQuantity < returnItem.Quantity;
});

以及上面使用的变量对应的类型:

public class ReturnItem
{
    public int OrderItemId {get; set;}
    public string ItemNumber {get; set;}
    public int Quantity {get; set;}
    // There's more properties but these are the ones that matter
{

public class OrderItem
{
    public int OrderItemId {get; set;}
    public string ItemNumber {get; set;}
    public int Quantity {get; set;}
    // There's more properties but these are the ones that matter
{

我希望 var invalidQuantityItems将是 IEnumerable<ReturnItems>单个商品的数量大于订购数量(即他们试图退回的数量超过最初订购的数量)。

干杯!

最佳答案

小修正 - 当前实现的时间复杂度是 O(N*M),你能得到的最好的是 O(N+M)。

问题是如何有效地关联这两个集合。在 LINQ 中,这是通过 joins 实现的。 ,对于这种一对多类型的关联 - group join . || 条件的等效项将是 Union两组连接的结果(匹配集)。

谈到可读性、LINQ 和连接,最好的方法是使用 LINQ 查询 语法(有些人也称它为理解 语法)是有原因的。 p>

所以有问题的查询可以有效地(并且希望可读)重写如下:

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;

关于c# - 优化具有多个条件的嵌套 where 子句的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56707262/

相关文章:

algorithm - 动态编程:允许互换时安装路灯

java - 比较来自 JSON 解析器的值

c# - 如何将 DbContext 实现注入(inject) Prism ViewModel 构造函数?

c# - 如何在一个事件方法中添加不同的按钮点击?

c# - 传递带有已指定参数的方法调用

c# - 监控一个进程的子进程

c# - 通过 WCF 公开自定义类中的成员函数

C#:将 JSON 原语反序列化为 .NET 复杂类型

.net - 拉伸(stretch)控件以填充 ItemsControl

algorithm - 将 100 到 4000000 之间的所有值相加,这些值可以被 3 或 5 整除但不能同时被 3 和 5 整除