【问题标题】:Comparing two large generic lists比较两个大型通用列表
【发布时间】:2012-08-15 09:26:09
【问题描述】:

我找不到具体的例子,所以我发布了这个问题。任何帮助表示赞赏。

我有两个大型通用列表,都包含超过 30 万个项目。

我正在循环第一个列表以拉回信息并即时为新列表生成一个新项目,但我需要在第二个列表中搜索并返回一个值,基于三个匹配条件,如果找到添加到列表中,但是您可以想象,执行 300k * 300k 次需要时间。

有什么方法可以更有效地做到这一点?

我的代码:

var reportList = new List<StocksHeldInCustody>();
foreach (var correctDepotHolding in correctDepotHoldings)
  {
    var reportLine = new StocksHeldInCustody();
    reportLine.ClientNo = correctDepotHolding.ClientNo;
    reportLine.Value = correctDepotHolding.ValueOfStock;
    reportLine.Depot = correctDepotHolding.Depot;
    reportLine.SEDOL = correctDepotHolding.StockCode;
    reportLine.Units = correctDepotHolding.QuantityHeld;
    reportLine.Custodian = "Unknown";
    reportLine.StockName = correctDepotHolding.StockR1.Trim() + " " + correctDepotHolding.StockR2.Trim();

    //Get custodian info

    foreach (var ccHolding in ccHoldList)
    {
      if (correctDepotHolding.ClientNo != ccHolding.ClientNo) continue;
      if (correctDepotHolding.Depot != ccHolding.Depot) continue;
      if (correctDepotHolding.StockCode != ccHolding.StockCode) continue;
      if (correctDepotHolding.QuantityHeld != ccHolding.QuantityHeld) continue;
      reportLine.Custodian = ccHolding.Custodian;
      break;
    }
    reportList.Add(reportLine);
  }

【问题讨论】:

  • 在对象中创建所有变量的哈希值并只检查这些,它必须运行得很快
  • 数据的来源是什么?如果它是一个像样的数据库,那么这方面可能会更好。
  • 更新了我的通用答案,详细介绍了如何在 linq 中执行外部联接

标签: c# .net-4.0


【解决方案1】:

正如 Pranay 所说,连接可能就是您想要的:

var query = from correct in correctDepotHoldings
            join ccHolding in ccHoldList
              on new { correct.ClientNo, correct.Depot,
                       correct.StockCode, correct.QuantityHeld }
              equals new { ccHolding.ClientNo, ccHolding.Depot,
                           ccHolding.StockCode, ccHolding.QuantityHeld }
            // TODO: Fill in the properties here based on correct and ccHolding
            select new StocksHeldInCustody { ... };
var reportList = query.ToList();

【讨论】:

  • 嗨,我在关键字“equals”和“ccHolding”上遇到错误,我需要在使用它之前将其声明为变量吗?
  • @DavidJohnson:糟糕,忘记了“输入”部分。查看我的编辑 - 如果您是 LINQ 新手,我会留出一些时间来全面学习它。
  • 谢谢-我正在尝试,但如果它只是随机组成,没有图案,我想这只是一个学习学习学习的案例!再次感谢。
  • 乔恩,我已经修改了我的问题,你能帮忙吗?
  • @DavidJohnson:不是现在——但如果你搜索“left outer join linq”,你会得到很多点击。
【解决方案2】:

您可以将查找列表中的数据移动到字典中,键是您正在搜索的 3 个项目的唯一哈希。然后您将获得非常快速的查找并节省数百万次迭代。

【讨论】:

    【解决方案3】:

    查看我的完整帖子:Linq Join on Mutiple columns using Anonymous type

    利用适合您的 Linq 内连接。

    var list =  ( from x in entity
               join y in entity2 
              on new { x.field1, x.field2 } 
            equals new { y.field1, y.field2 }
            select new entity { fields to select}).ToList();
    

    在多个字段上加入 linq

    EmployeeDataContext edb= new EmployeeDataContext();
    var cust = from c in edb.Customers
               join d in edb.Distributors on
                 new { CityID = c.CityId, StateID = c.StateId, CountryID = c.CountryId,
                       Id = c.DistributorId }   
               equals
                 new { CityID = d.CityId, StateID = d.StateId, CountryID = d.CountryId,
                       Id = d.DistributorId }   
               select c;
    

    【讨论】:

    • 连接语法无效。请参阅我的答案以获取正确示例。
    【解决方案4】:

    使用 LINQ 加入列表并以您喜欢的方式返回。

    例如

    var list1 = GetMassiveList();
    var list2 = GetMassiveList();
    
    var list3 = from a in list1
                join b in list2
                     on new { a.Prop1, a.Prop2 } equals
                        new { b.Prop1, b.Prop2 } 
                select new { a.Prop1, b.Prop2 };
    

    要进行外部连接,您可以使用 DefaultIfEmpty() 此示例将连接的 RIGHT 部分设置为默认对象(通常为 null),以用于未进行连接的情况。

    例如

    from a in list1
    join b in list2
        on new { a.Prop1, a.Prop2 } equals
           new { b.Prop1, b.Prop2 } 
    into outer
    from b in outer.DefaultIfEmpty()
    select new 
        Prop1 = a.Prop1,
        Prop2 = b != null ? b.Prop2 : "Value for Prop2 if the b join is null"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-19
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多