C#中如何高效搜索自定义类构成的嵌套列表?
优化嵌套列表的匹配搜索方案
原始代码与类定义
自定义类
public class Object_Params { public string category { get; set; } public List<string> obj_name { get; set; } public List<string> param_displayname { get; set; } public List<string> param_path { get; set; } public List<string> trait_type { get; set; } } public class Sequencer_Object { public string obj_name { get; set; } public string param_path { get; set; } public string trait_type { get; set; } public dynamic data_points { get; set; } public string friendly_type { get; set; } public string friendly_param { get; set; } }
原始搜索逻辑
//"seq_obj" comes from somewhere else. Sequencer_Object _s = new Sequencer_Object() { obj_name = seq_obj["obj_name"], trait_type = seq_obj["trait_type"], data_points = seq_obj["data_points"], param_path = seq_obj["param_path"] }; foreach (Object_Params _obj in _objects) { for (int x = 0; x < _obj.param_path.Count; x++) { //if found, set the friendly names if (_obj.param_path[x] == _s.param_path && _obj.obj_name[x] == _s.obj_name) { _s.friendly_param = _obj.param_displayname[x]; _s.friendly_type = _obj.category; goto endsearch; } } } endsearch:
优化方案
方案1:用LINQ简化单次搜索逻辑
使用LINQ的SelectMany将嵌套列表扁平化,再通过FirstOrDefault直接定位第一个匹配项,代码更简洁,且找到匹配后立即停止遍历,无需goto:
//"seq_obj" comes from somewhere else. Sequencer_Object _s = new Sequencer_Object() { obj_name = seq_obj["obj_name"], trait_type = seq_obj["trait_type"], data_points = seq_obj["data_points"], param_path = seq_obj["param_path"] }; var match = _objects .SelectMany(obj => obj.param_path.Select((path, index) => new { Category = obj.category, FriendlyParam = obj.param_displayname[index], Path = path, ObjName = obj.obj_name[index] })) .FirstOrDefault(item => item.Path == _s.param_path && item.ObjName == _s.obj_name); if (match != null) { _s.friendly_param = match.FriendlyParam; _s.friendly_type = match.Category; }
方案2:构建字典索引提升多次搜索效率
如果需要频繁执行此类搜索,提前构建以(obj_name, param_path)为键的字典索引,将初始化时的遍历成本分摊到多次搜索中,每次查询仅需O(1)时间:
// 初始化索引(仅需执行一次) var paramLookup = new Dictionary<(string ObjName, string ParamPath), (string FriendlyParam, string FriendlyType)>(); foreach (var obj in _objects) { for (int i = 0; i < obj.param_path.Count; i++) { var key = (obj.obj_name[i], obj.param_path[i]); // 若存在重复键,可根据业务需求选择覆盖或跳过 if (!paramLookup.ContainsKey(key)) { paramLookup[key] = (obj.param_displayname[i], obj.category); } } } // 后续搜索直接查询索引 Sequencer_Object _s = new Sequencer_Object() { obj_name = seq_obj["obj_name"], trait_type = seq_obj["trait_type"], data_points = seq_obj["data_points"], param_path = seq_obj["param_path"] }; if (paramLookup.TryGetValue((_s.obj_name, _s.param_path), out var result)) { _s.friendly_param = result.FriendlyParam; _s.friendly_type = result.FriendlyType; }
内容的提问来源于stack exchange,提问作者CocoaMix86
相关产品推荐
相关产品推荐

