C#通过Lambda表达式比对请求响应数组筛选列表的实现问题
原有代码报错原因
原实现存在3个核心问题,导致运行报错或匹配逻辑失效:
- 比对对象错误:
param["array"]是存储在object类型里的整个数组对象,直接调用ToString()只会输出该对象的运行时类型名称,和单个数组项的Value属性值做相等判断永远无法得到正确结果。 - 缺失必要筛选条件:没有添加
className == "aClass"的前置过滤,会遍历所有分类数据做无效比对。 - 硬编码索引鲁棒性极差:直接通过固定下标
[0]/[1]/[2]/[3]取数组项,一旦请求或响应的数组项顺序变动,就会出现匹配错误甚至索引越界报错,也没有按照CodeID做精准的键值匹配。
修正后的实现
首先定义和数组项结构匹配的公共类(如果已有对应模型可以跳过这步):
public class CodeOption { public string GroupID { get; set; } public string CodeID { get; set; } public string Value { get; set; } }
然后在筛选逻辑前先把请求参数里的数组转成结构化数据,再做匹配,逻辑不依赖数组固定顺序:
// 注意:请求示例中第4个数组项的键写为"ClassID"属于笔误,以下代码按统一字段名GroupID处理 // 从param中取出请求传入的数组,转换为按CodeID索引的Value字典,方便快速比对 // 若使用Newtonsoft.Json做序列化,用以下代码转换: var requestCodeList = Newtonsoft.Json.Linq.JArray.FromObject(param["array"]) .ToObject<List<CodeOption>>(); // 若使用System.Text.Json做序列化,替换为以下转换代码: // var requestCodeList = System.Text.Json.JsonSerializer.Deserialize<List<CodeOption>>( // ((System.Text.Json.JsonElement)param["array"]).GetRawText() // ); var requestCodeMap = requestCodeList.ToDictionary(item => item.CodeID, item => item.Value); // 执行筛选 resultList.AddRange(tempList.Where(um => // 先匹配className为aClass um.className == "aClass" // 再校验请求传入的所有编码项,在当前分类的数组中都存在CodeID一致、Value一致的项 && requestCodeMap.All(reqKv => um.array.Any(resItem => resItem.CodeID == reqKv.Key && resItem.Value == reqKv.Value ) ) ));
逻辑说明
- 该实现不会因为数组项顺序变化出现匹配错误,只要CodeID对应的Value和请求传入值完全一致就判定为匹配。
- 按你给出的示例数据,只有aClass的A/B/C/D四个项Value全为1,和请求参数完全匹配,bClass、cClass的D项Value为0,会被自动过滤。
- 如果需要严格匹配两个数组完全等长(即不允许响应数组比请求数组多出E这类额外项),可以在判断条件中追加
&& um.array.Count == requestCodeList.Count即可。
内容的提问来源于stack exchange,提问作者codytimeess
相关产品推荐
相关产品推荐

