基于LINQ实现带随机访问能力的有序集合排序方案问询
问题:用LINQ简化有序集合构建并保留随机访问能力
现有需求:对由Parallel.For()生成的无序Dictionary<(int, int), SimulationPoint>(键为(射线编号, 反射次数),值为包含bool hasHit字段的结构体),筛选出hasHit为false的元素,生成支持随机访问的有序嵌套集合SortedList<int, SortedList<int, SimulationPoint>>。
当前实现代码如下:
SortedList<int, SortedList<int, SimulationPoint>> sl = new SortedList<int, SortedList<int, SimulationPoint>>(); for(int i=0; i<source.Reflections+1; i++) { sl.Add(i, new SortedList<int, SimulationPoint>()); } var q = source.SimulationResult.Where(x => !x.Value.hasHit); foreach (var qa in q) { sl[qa.Key.Item2].Add(qa.Key.Item1, qa.Value); }
希望用LINQ简化代码,但GroupBy返回的IGrouping<int, SimulationPoint>仅支持顺序访问,无法满足随机访问需求,求可行方案。
解决方案
方案1:仅保留含数据的反射次数分组(更简洁)
如果不需要为无数据的反射次数创建空SortedList,可以直接通过LINQ将分组结果转换为嵌套的SortedList,同时保留随机访问能力:
// .NET 6+ 可用 ToSortedList() 直接生成外层有序集合 var sl = source.SimulationResult .Where(x => !x.Value.hasHit) .GroupBy(x => x.Key.Item2) // 按反射次数分组 .ToDictionary(g => g.Key, g => new SortedList<int, SimulationPoint>(g.ToDictionary(kv => kv.Key.Item1, kv => kv.Value))) .ToSortedList(); // 兼容旧版本.NET(如.NET Framework) var sl = new SortedList<int, SortedList<int, SimulationPoint>>( source.SimulationResult .Where(x => !x.Value.hasHit) .GroupBy(x => x.Key.Item2) .ToDictionary(g => g.Key, g => new SortedList<int, SimulationPoint>(g.ToDictionary(kv => kv.Key.Item1, kv => kv.Value))) );
方案2:保留所有反射次数分组(与原逻辑一致)
如果需要和原代码一样,为0到source.Reflections的所有反射次数都初始化空SortedList(即使无匹配数据),可以结合Enumerable.Range和LINQ的批量操作:
// 先初始化所有反射次数的空SortedList var sl = new SortedList<int, SortedList<int, SimulationPoint>>( Enumerable.Range(0, source.Reflections + 1) .ToDictionary(i => i, i => new SortedList<int, SimulationPoint>()) ); // 用LINQ筛选后批量填充数据 source.SimulationResult .Where(x => !x.Value.hasHit) .ToList() // 避免多次枚举原字典 .ForEach(kv => sl[kv.Key.Item2].Add(kv.Key.Item1, kv.Value));
内容的提问来源于stack exchange,提问作者NoseHornScribe
相关产品推荐
相关产品推荐

