使用linq在一个属性c#上过滤两个列表

前端之家收集整理的这篇文章主要介绍了使用linq在一个属性c#上过滤两个列表前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有两个对象,即卡和交易:
  1. Card:
  2. public string CardID {get; set;}
  3. public string TransactionRef {get; set;}
  4.  
  5. Transaction:
  6. public string TxnID {get; set;}
  7. public string TxnDetails {get; set;}

注意:TransactionRef的格式为Date | TxnID

我还列出了两个对象List< Card> cardDetails and List< Transaction> transDetails

  1. cardDetails:
  2. {CardID = '1',TransactionRef = '20150824|Guid1'}
  3. {CardID = '2',TransactionRef = '20150824|Guid2'}
  4. {CardID = '3',TransactionRef = '20150824|Guid3'}
  5.  
  6. transDetails:
  7. {TxnID = '23',TxnDetails = 'Guid1'}
  8. {TxnID = '24',TxnDetails = 'Guid2'}

我想使用基于TxnDetails的transDetails过滤cardDetails,以便过滤掉第二个列表中不包含TxnDetails的项目.

这应该是输出

  1. cardDetails:
  2. {CardID = '3',TransactionRef = '20150824|Guid3'}

我试过这样使用linq:

  1. cardDetails = cardDetails.Where(x => transDetails.Any(y => x.TransactionRef.Contains(y.TxnDetails) == false)).ToList();

但它总是将列表返回为空白.我已尝试此查询的许多变体但没有成功.我知道在搜索它们之前和之后已经问过这个问题,并且尝试了他们的解决方案我仍然无法做到正确.

任何人都可以建议我的查询有什么问题吗?

注意:我忘了提到的一件事是这些列表可以包含1000条记录.所以表现也很重要.

解决方法

这应该做到这一点
  1. var cards =
  2. from card in cardDetails
  3. let txnDetails = GetTxnDetails(card)
  4. where ! transDetails.Any(t => t.TxnDetails == txnDetails)
  5. select card;
  6.  
  7.  
  8. static string GetTxnDetails(Card card)
  9. {
  10. return card.TransactionRef.Split('|')[1];
  11. }

小提琴:https://dotnetfiddle.net/b9ylFe

优化这一点的一种方法是将所有可能的事务细节存储在哈希集中.然后,查找应该非常接近O(1)(假设公平的哈希码分布)而不是O(n) – 使算法的总体复杂度从O(n * k)下降到O(n k).

  1. var allTxnDetails = new HashSet<string>(transDetails.Select(t => t.TxnDetails));
  2.  
  3. var cards =
  4. from card in cardDetails
  5. let txnDetails = GetTxnDetails(card)
  6. where ! allTxnDetails.Contains(txnDetails)
  7. select card;

小提琴:https://dotnetfiddle.net/hTYCbj

猜你在找的C#相关文章