Linq和词典的范围

时间:2009-09-01 14:39:41

标签: c# linq dictionary

我创建了一个Range类型:

public class Range<T> where T : IComparable<T>
{
    public Range(T min, T max) : this(min, max, false) { }
    public Range(T min, T max, bool upperbound)
    {
    }
    public bool Upperbound { get; private set; }
    public T Min { get; private set; }
    public T Max { get; private set; }
    public bool Between(T Value)
    {
        return Upperbound ? (Min.CompareTo(Value) < 0) && (Value.CompareTo(Max) <= 0) : (Min.CompareTo(Value) <= 0) && (Value.CompareTo(Max) < 0);
    }
}

我想在字典中使用它作为键,允许我根据范围进行搜索。是的,范围可以重叠或者可能存在间隙,这是设计的一部分。它看起来很简单,但我希望搜索更容易一些!我想比较一个范围与它的类型T的值,所以我可以使用:myRange == 10而不是myRange.Between(10)。

如何? :-) (不想打破这个。我可能会找到答案,但也许我正在重新发明轮子或其他什么。)


我想用这本词典做些什么?好吧,一般来说我会使用范围本身作为关键。范围将不仅仅用于字典。我正在处理大量具有最小/最大范围的数据,我需要根据相同的最小/最大值将这些数据组合在一起。字典中的值是这些产品的列表,它们都具有相同的范围。通过使用范围,我可以快速找到需要添加产品的正确列表。 (如果没有找到列表,则创建一个新条目。)

一旦我有按范围分组的产品列表,我就可以开始搜索特定范围内的值。基本上,这可能是所有值的字典上的Linq查询,其中提供值介于最小值和最大值之间。

我实际上正在处理两个这样的列表。在一个中,范围是上限而另一个是下限。可能会有更多这类列表,我首先需要根据其范围收集数据,然后在其中查找特定项目。

我可以使用List吗?可能,但是根据范围本身,我不会对数据进行独特的分组。列表列表呢?可能,但后来我再次考虑字典。 : - )


范围示例:我有多个项目,范围是0到100.其他项目的范围是0到1,1到2,2到3等。更多的项目范围是0到4,4到6,6到8等。我甚至有0到0.5,0.5到1,1到1.5等范围的项目。所以,首先我会根据它们的范围对所有项目进行分组,所以所有项目都是范围为1到2的项目将在一个列表中,而范围为0到100的所有项目将在不同的列表中。我已经计算出我将处理大约50个可以相互重叠的不同范围。但是,我有超过25000项需要像这样分组。

接下来,我从另一个来源获得一个值。例如,我需要找到的值1.12。所以这次我使用Linq搜索字典来查找1.12将在键范围内的所有项目列表。因此,我会找到1到2,1到1.5甚至0到100的范围。在这些范围的后面会有我需要为此值处理的项目列表。然后我可以继续前进到下一个值,大约4000个不同的值。最好一切都应该用5秒完成。

1 个答案:

答案 0 :(得分:6)

在字典中使用密钥需要覆盖GetHashCodeEquals。基本上你会根据最小值和最大值以及Upperbound创建一个哈希值。通常,您在每个组件上调用GetHashCode并将它们组合在一起,例如:

public override int GetHashCode()
{
    int result = 17;
    result = result * 31 + Min.GetHashCode();
    result = result * 31 + Max.GetHashCode();
    result = result * 31 + Upperbound ? 1 : 0;
}

您还需要进行相等测试。

我不确定你的意思是“允许我根据范围进行搜索”。你能给出一些展示你如何使用这种能力的示例代码吗?我不完全确定它是否符合正常的字典方法......

我建议您不要重载==运算符以允许您使用它进行包含测试。范围等于范围内的值,因此使用该范围的代码不会非常直观。

(我个人也将Between重命名为Contains。)