我正在寻找下面场景的集合类:
将填充到集合中的Ip2Location
类型的项目示例:
public class Ip2Location
{
public long IpFrom {get; set;}
public long IpTo {get; set;}
public string Country {get; set;}
}
IpFrom IpTo Country
16909056 16909311 AU
16909312 16941055 US
针对集合的项目查找是通过指定的IP完成的,如下所示:
IpFrom < currentIp < IpTo
非常感谢任何想法,包括参考链接!
比较:HashSet, SortedSet
有没有更好的收藏类?
参考:以下链接中的比较表: http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx
更新:
使用Array.BinarySearch的问题:
var index = Array.BinarySearch(ipCountries, new IpCountry { IpFrom = 16909056}, new Ip2LocationComparer());
它在少量行中工作,在300k项目中不起作用(例如索引是 - (totalrow + 1))。搜索项目加载在300 K项目集合中。
public class Ip2LocationComparer: IComparer<IpCountry>
{
public int Compare(IpCountry x, IpCountry y)
{
if (x != null && y != null)
return (x.IpFrom <= y.IpFrom && y.IpFrom <= x.IpTo)? 0 : -1;
return -1;
}
}
更新2
我把它改成了
public class Ip2LocationComparer: IComparer<IpCountry>
{
public int Compare(IpCountry x, IpCountry y)
{
if (x != null && y != null)
{
if (x.IpFrom > y.IpFrom)
return 1;
if (x.IpFrom < y.IpFrom)
return -1;
if (x.IpFrom == y.IpFrom)
{
if (y.IpFrom > x.IpTo)
return 1;
if (y.IpFrom < x.IpTo)
return -1;
}
}
return 0;
}
但是BinarySearch的索引返回仍然是指向性的,它位于匹配项和后续项之间。例如如果我的搜索IpFrom为3,则索引介于2和4之间。为什么它不返回2?我还没有测试过IpTo场景。
任何想法都会受到赞赏!
答案 0 :(得分:4)
您可以将其存储在数组中。
如果您在填充后对数组进行了排序,那么BinarySearch将是一种非常快速的方法来查找currentIp
落在哪里。
答案 1 :(得分:0)
数据结构方面,您可以尝试字典或排序列表,但有300000项,您可能会遇到问题。不过,我很想听听结果。具有BinarySearch的普通数组也可能不是一个糟糕的选择。
您还可以考虑利用计算机上的所有核心进行快速查找。您可以在大多数colllections上使用.AsParallel() extension method,这将准备集合以便在多个核心上进行查询。