如何使用LINQ实现两个复杂列表比较并筛选有效/无效价格记录
用LINQ实现有效与无效价格记录筛选
需求说明
现有两个列表:items(包含商品及其对应的包装类型)和prices(商品包装的定价记录),需要筛选出有效定价(商品和包装的组合存在于items中)和无效定价(商品包装组合不存在),替代原有的嵌套循环逻辑。
LINQ实现代码
static void FindItemswithInvalidPackages() { List<Item> items = new List<Item>() { new Item { Id = 1, Name = "Item 01", Packages = new List<Package> { new Package { Id = 1, Name = "SINGLE" }, new Package { Id = 2, Name = "PACK" } } }, new Item { Id = 2, Name = "Item 02", Packages = new List<Package> { new Package { Id = 1, Name = "SINGLE" }, new Package { Id = 2, Name = "PACK" } } }, new Item { Id = 3, Name = "Item 03", Packages = new List<Package> { new Package { Id = 1, Name = "SINGLE" }, new Package { Id = 2, Name = "PACK" } } }, new Item { Id = 4, Name = "Item 04", Packages = new List<Package> { new Package { Id = 1, Name = "SINGLE" }, new Package { Id = 2, Name = "PACK" } } }, new Item { Id = 5, Name = "Item 04", Packages = new List<Package> { new Package { Id = 1, Name = "SINGLE" }, new Package { Id = 2, Name = "PACK" } } }, new Item { Id = 6, Name = "Item 06", Packages = new List<Package> { new Package { Id = 1, Name = "SINGLE" }, new Package { Id = 2, Name = "PACK" } } } }; List<RetailPrice> prices = new List<RetailPrice>() { new RetailPrice { Item = 1, Package = 1, Price = 1 }, new RetailPrice { Item = 2, Package = 2, Price = 2 }, new RetailPrice { Item = 3, Package = 1, Price = 3 }, new RetailPrice { Item = 4, Package = 2, Price = 4 }, new RetailPrice { Item = 5, Package = 3, Price = 5 }, // 无效记录 new RetailPrice { Item = 6, Package = 2, Price = 6 } }; // 用LINQ生成有效商品-包装组合的哈希集合 var validItemPackagePairs = new HashSet<string>( items.SelectMany(item => item.Packages, (item, package) => $"{item.Id}|{package.Id}") ); // 筛选有效和无效价格 var goodPrices = prices.Where(p => validItemPackagePairs.Contains($"{p.Item}|{p.Package}")).ToList(); var badPrices = prices.Where(p => !validItemPackagePairs.Contains($"{p.Item}|{p.Package}")).ToList(); }
关键逻辑拆解
生成有效组合集合:
- 使用
SelectMany扁平化嵌套的items和Packages,把每个商品的所有包装转换成"商品ID|包装ID"的字符串格式 - 直接传入HashSet的构造函数,避免额外的循环添加操作
- 使用
筛选价格记录:
- 用
Where方法分别过滤出存在于有效组合中的goodPrices,以及不存在的badPrices - 最后用
ToList()把LINQ查询结果转换成List,和原代码的返回类型保持一致
- 用
进阶优化(可选)
如果不想用字符串拼接,可以用值类型元组来存储有效组合,避免字符串操作的开销:
// 用元组存储有效组合 var validPairs = new HashSet<(int ItemId, int PackageId)>( items.SelectMany(item => item.Packages, (item, package) => (item.Id, package.Id)) ); // 筛选时直接匹配元组 var goodPrices = prices.Where(p => validPairs.Contains((p.Item, p.Package))).ToList(); var badPrices = prices.Where(p => !validPairs.Contains((p.Item, p.Package))).ToList();
内容的提问来源于stack exchange,提问作者Belmiris
相关产品推荐
相关产品推荐

