C#中如何基于ID合并列车列表并筛选未来有效班次
解决方案:筛选跨站点列车并过滤未来班次
你遇到的问题核心是Intersect默认使用引用相等性来比较Train对象——即使两个列车ID相同,它们是不同的实例,所以Intersect找不到交集。下面提供两种可行的解决方案,同时满足你过滤未来班次和排序的需求:
方法1:使用Linq的Where+Any实现筛选
这种方法更直观,不需要额外定义比较器,直接通过ID匹配跨站点的列车,再过滤和排序:
// 获取出发站和到达站 var departingStation = App.Stations.FirstOrDefault(s => s.Name == "Birmingham New Street"); var arrivingStation = App.Stations.FirstOrDefault(s => s.Name == "Marston Green"); if (departingStation == null || arrivingStation == null) { // 处理站点不存在的情况,比如返回空列表 return new List<Train.Train>(); } // 筛选符合条件的列车 var validTrains = departingStation.TrainsArriving // 只保留未来的班次 .Where(train => train.Arrival > DateTime.Now) // 筛选同时存在于到达站的列车(按ID匹配) .Where(departingTrain => arrivingStation.TrainsArriving .Any(arrivingTrain => arrivingTrain.ID == departingTrain.ID)) // 按到达时间升序排序 .OrderBy(train => train.Arrival) .ToList();
方法2:自定义IEqualityComparer<Train>使用Intersect
如果你更倾向于使用Intersect,可以定义一个基于ID的比较器,让Intersect按ID识别相同列车:
步骤1:定义比较器
public class TrainByIdComparer : IEqualityComparer<Train.Train> { public bool Equals(Train.Train x, Train.Train y) { if (x == null || y == null) return false; // 按ID判断相等性 return x.ID == y.ID; } public int GetHashCode(Train.Train obj) { // 基于ID生成哈希码 return obj.ID.GetHashCode(); } }
步骤2:使用比较器结合Intersect
var departingStation = App.Stations.FirstOrDefault(s => s.Name == "Birmingham New Street"); var arrivingStation = App.Stations.FirstOrDefault(s => s.Name == "Marston Green"); if (departingStation == null || arrivingStation == null) { return new List<Train.Train>(); } var validTrains = departingStation.TrainsArriving .Intersect(arrivingStation.TrainsArriving, new TrainByIdComparer()) // 过滤未来班次 .Where(train => train.Arrival > DateTime.Now) // 按时间升序排序 .OrderBy(train => train.Arrival) .ToList();
关键说明
- 过滤未来班次:通过
train.Arrival > DateTime.Now排除已经驶过的列车,注意如果需要考虑时区,可以替换为DateTime.UtcNow并确保列车的Arrival也是UTC时间。 - 排序:使用
OrderBy(train => train.Arrival)保证结果按到达时间从早到晚排列。 - 空值处理:加入了站点不存在的判断,避免空引用异常,你可以根据业务需求调整这部分逻辑。
内容的提问来源于stack exchange,提问作者Jaquarh
相关产品推荐
相关产品推荐

