LINQ和排序到具有随机访问能力的顺序集合

ycggw6v2  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(147)

我有这样的代码:

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); 
}

我想生成source.SimulationResult集合的排序输出,它是Dictionary<(int, int), SimulationPoint>。(这个字典是使用Parallel.For()循环生成的,所以所有项的顺序都是随机的。)
字典关键字:只有从源发射的光线数(例如0-〉100)和在场景中反弹时的反射数(例如0-〉10):(int光线,int反射)。
字典值:SimulationPoint是光线跟踪过程的输出点,其中最重要的元素是它包含一个字段bool hasHit,该字段指示该点是否命中场景中的元素。(我们在这里查找这些错误,因此是source.SimulationResult.Where(x=>!x.Value.hashit);)(FWIW,此struct SimulationPoint还包含Ray & Reflection数据。)
一般来说,这是可行的。但是我真的很喜欢LINQ语法和一行程序的概念,因为它可以避免多个嵌套循环。有人知道如何使用LINQ扩展来简化这一点吗?
请记住,我希望能够在sl集合中根据用户的选择跳转,这是我在GroupBy(x=>x.Key.Item2, x=>x.Value)方法的IGrouping<int, SimulationPoint>输出中遇到的问题-它只能使用foreach循环按顺序访问,即使使用OrderBy(x.Key.Item2).ThenBy(x.Key.Item1)排序也是如此。

w8f9ii69

w8f9ii691#

我建议添加一个类似于ToDictionary的扩展方法(组)来执行ToSortedList。然后,使用该扩展方法,您可以使用GroupBy(它在内部创建Dictionary ...)来创建SortedList。在内部,您实际上是在源数据上运行了两次,但看起来并不像是在讨论大量数据。

var sl2 = q.GroupBy(kvp => kvp.Key.Reflection) // group by outer SortedList Key
           .ToSortedList(kvpg => kvpg.Key, // outer SortedList Key (Reflection)
                         // outer SortedList Value (SortedList: Ray -> SimulationPoint)
                         kvpg => kvpg.ToSortedList(kvp => kvp.Key.Ray, // inner SortedList Key (Ray)
                                                   kvp => kvp.Value) // inner SortedList Value (SimulationPoint)
                        );

下面是扩展方法的定义:

public static class IEnumerableExt {
    public static SortedList<TKey, TValue> ToSortedList<TItem, TKey, TValue>(this IEnumerable<TItem> items, Func<TItem, TKey> keyFn, Func<TItem, TValue> valueFn) {
        var ans = new SortedList<TKey, TValue>();
        foreach (var item in items)
            ans.Add(keyFn(item), valueFn(item));
        return ans;
    }
    public static SortedList<TKey, TValue> ToSortedList<TKey, TValue>(this IEnumerable<TValue> items, Func<TValue, TKey> keyFn) {
        var ans = new SortedList<TKey, TValue>();
        foreach (var item in items)
            ans.Add(keyFn(item), item);
        return ans;
    }
    public static SortedList<TKey, TKey> ToSortedList<TKey>(this IEnumerable<TKey> items) {
        var ans = new SortedList<TKey, TKey>();
        foreach (var item in items)
            ans.Add(item, item);
        return ans;
    }
}

相关问题