0

在 Linq 中使用 SortedDictionary 并遍历它提供的 KeyValuePair 时,我可以确保复杂的 linq 查询将按升序执行它吗?这是一个简短的,虽然有点令人困惑的例子:

Random r = new Random();
//build 100 dictionaries and put them into a sorted dictionary
//with "priority" as the key and it is a number 0-99.
SortedDictionary<int, Dictionary<int, double>> sortedDict = 
    new SortedDictionary<int, Dictionary<int, double>>();
for (int i = 0; i < 100; i++)
{
    Dictionary<int, double> dict = new Dictionary<int, double>();
    //create the dictionary and a random 10 k/v pairs
    for (int j = 0; j < 10; j++)
    {
        dict[r.Next(0, 100)] = r.NextDouble() * i * 10;
    }
    sortedDict[i] = dict;
}

IEnumerable<int> keys = Enumerable.Range(0, 100);

//the goal is to find the FIRST existence of the "key" inside one
//of the inner dictionaries going through the SortedDictionary IN ORDER
//this appears to work:
var qry = from key in keys
          from priority in sortedDict
          where priority.Value.ContainsKey(key)
          let value = priority.Value[key]
          group value by key into keyGroup
          let firstValue = keyGroup.First()
          select new { Key = keyGroup.Key, Value = firstValue };

// the result is as expected, a list of the numbers at most 0-99 and their
// value found in the dictionary with the lowest "priority"

问题:

  1. 它似乎有效,但我可以依靠这种行为吗?
  2. 这是有效的,还是小组把它扔掉了?
  3. 添加“sortedDict.Reverse()”是否也能正常工作?(看来)
  4. Plinq 将如何处理这个问题——它是否仍然保持一致?

如果不能保证这一点,我知道如何在事后将“优先级”拉入分组并按其排序。但我宁愿不...

4

3 回答 3

3
  1. 是的,您可以信任 SortedDictionary 的顺序。否则将毫无意义:)
  2. 如果没有“let”子句,效率会更高一些。做就是了:

    var qry = from key in keys
              from priority in sortedDict
              where priority.Value.ContainsKey(key)
              let value = priority.Value[key]
              group value by key into keyGroup
              select new { Key = keyGroup.Key, Value = keyGroup.First() };
    

    但是,您仍然需要大量地浏览字典。您基本上不想要从键到包含该键的优先级的反向映射吗?这可以更有效地构建。正如你所说,这个例子很混乱。如果你能告诉我们你想在你的真实代码中实现什么,我们可能会想出更好的东西。(如果确实是这种情况,我当然可以解决这个问题 - 我宁愿不这样做,然后发现现实非常不同!)

  3. 调用 Reverse() 确实会起作用 - 但它会缓冲所有数据。如果你想要它以相反的顺序,我建议你给 SortedDictionary 一个合适的 IComparer 开始。

  4. 就订单而言,并行 LINQ 是“有趣的”。现在可能会有所不同,但不久前当我使用它绘制 Mandelbrot 集时我很开心......

于 2009-02-11T20:00:25.937 回答
1

这是有关哪些 linq 方法保留顺序的答案。

目测查询,看起来您有:

  keys.SelectMany(...)
    .Where(...)
    .GroupBy(...)
    .Select(g => g.First())
    .Select(...);

所有这些都会以某种方式保持排序。

于 2009-02-11T23:45:06.910 回答
0
  1. 是的你可以。SortedDictionary 无法取消排序。保证保持排序,即使它抛出异常
  2. 排序是有效的。您可以通过了解使用什么类型的领域知识等更有效地做到这一点,但在 99,99% 的情况下,这样做会很多而且不值得
  3. 是的:)
  4. 看来我错了,plinq 有订购问题。请参阅乔恩的帖子
于 2009-02-11T19:51:48.830 回答