【发布时间】:2015-11-22 23:32:06
【问题描述】:
我有两个列表:
带有 CancelledFlights 的 ListA
ListB 包含所有航班
我想从 ListB 中删除所有 CancelledFlights,其中所有航班不是按对象而是按属性 FlightNumber 进行比较。我如何使用 Lambda 或 LINQ 实现这一点?我知道如何在 LINQ 和 lambda 中选择,但不知道如何删除...
【问题讨论】:
我有两个列表:
带有 CancelledFlights 的 ListA
ListB 包含所有航班
我想从 ListB 中删除所有 CancelledFlights,其中所有航班不是按对象而是按属性 FlightNumber 进行比较。我如何使用 Lambda 或 LINQ 实现这一点?我知道如何在 LINQ 和 lambda 中选择,但不知道如何删除...
【问题讨论】:
你可以使用 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));
【讨论】:
cancelledFlightNumbers 替换为ListA .Select(x => x.FlightNumber)。
ListA 很大,则可能值得创建HashSet<T>,而不是List<T>。它只是var cancelledFlightNumbers = new HashSet<int>(ListA.Select(x => x.FlightNumber));。
HashSet 包装cancelledFlightNumbers,以便获得有效的解决方案。
我能想到两种方法,一种是使用 LINQ,一种是简单地使用 List<T> 的方法:
List<T> 方法:
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 本身并不能帮助您从列表中删除项目。
【讨论】: