【问题标题】:Remove items from a List which are in another List by a specific property?从列表中删除特定属性在另一个列表中的项目?
【发布时间】:2015-11-22 23:32:06
【问题描述】:

我有两个列表:

带有 CancelledFlights 的 ListA
ListB 包含所有航班

我想从 ListB 中删除所有 CancelledFlights,其中所有航班不是按对象而是按属性 FlightNumber 进行比较。我如何使用 Lambda 或 LINQ 实现这一点?我知道如何在 LINQ 和 lambda 中选择,但不知道如何删除...

【问题讨论】:

    标签: c# .net linq lambda


    【解决方案1】:

    你可以使用 linq 来做到这一点

    var cancelledFlightNumbers = ListA
        .Select(x => x.FlightNumber)
        .ToList();
    
    var cancelledFlightsRemoved = ListB
        .Where(x => !cancelledFlightNumbers.Contains(x.FlightNumber))
        .ToList();
    

    如果您的项目太多,那么您可以使用HashSet 来提高性能

    var cancelledFlightNumbers = new HashSet<int>(ListA.Select(x => x.FlightNumber));
    

    【讨论】:

    • 您好,感谢您的回答。我希望我理解正确:您仅将 ListA 的 FlightNumber 属性提取到一个新列表中,以使用此列表从 ListB 中删除航班?这真的需要吗?我的意思是不能直接在第二个查询中使用列表吗?
    • 是的,您是对的,您可以在第二个查询中将cancelledFlightNumbers 替换为ListA .Select(x =&gt; x.FlightNumber)
    • 如果ListA 很大,则可能值得创建HashSet&lt;T&gt;,而不是List&lt;T&gt;。它只是var cancelledFlightNumbers = new HashSet&lt;int&gt;(ListA.Select(x =&gt; x.FlightNumber));
    • 如果列表很大,那么您可能需要用HashSet 包装cancelledFlightNumbers,以便获得有效的解决方案。
    • @Yacoub:我有大约 >10.000 个项目。
    【解决方案2】:

    我能想到两种方法,一种是使用 LINQ,一种是简单地使用 List&lt;T&gt; 的方法:

    • List&lt;T&gt; 方法:

      allFlights.RemoveAll(flight => cancelledFlight.Any(cancelled => cancelled.FlightNumber == flight.FlightNumber);

    • LINQ 方法:

      // an IEqualityComparer<T> that can compare objects by FlightNumber. var flightNumberComparer = new FlightNumberComparer(); allFlights = allFlights.Except(cancelledFlights, flightNumberComparer).ToList();

    如您所见,对于这个简单的场景,RemoveAll 可能是最简单的。它会删除原始列表中的项目,而不是创建新列表,并且可能最容易编写。

    请记住,LINQ 是一种查询语言。它没有设计为具有 remove 操作。最多,它可以创建一个集合的过滤视图并基于它创建一个 new 列表(就像我们在这里所做的那样)。但 LINQ 本身并不能帮助您从列表中删除项目。

    【讨论】:

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