我有一个List of Structs
,它包含Id,以及x和y坐标的值:
public struct XYStruct
{
public int vertexId;
public double x;
public double y;
}
List<XYStruct> myList = new List<XYStruct>();
myList.Add(new XYStruct{ vertexId = 0, x = 0, y = 0});
myList.Add(new XYStruct{ vertexId = 1, x = 20, y = 0});
myList.Add(new XYStruct{ vertexId = 2, x = 40, y = 0});
myList.Add(new XYStruct{ vertexId = 3, x = 60, y = 0});
myList.Add(new XYStruct{ vertexId = 4, x = 80, y = 0});
myList.Add(new XYStruct{ vertexId = 5, x = 100, y = 0});
myList.Add(new XYStruct{ vertexId = 6, x = 0, y = 10});
myList.Add(new XYStruct{ vertexId = 7, x = 20, y = 10});
myList.Add(new XYStruct{ vertexId = 8, x = 40, y = 10});
myList.Add(new XYStruct{ vertexId = 9, x = 80, y = 10});
myList.Add(new XYStruct{ vertexId = 10, x = 100, y = 10});
myList.Add(new XYStruct{ vertexId = 6, x = 0, y = 20});
myList.Add(new XYStruct{ vertexId = 7, x = 20, y = 20});
myList.Add(new XYStruct{ vertexId = 8, x = 40, y = 20});
myList.Add(new XYStruct{ vertexId = 9, x = 80, y = 20});
myList.Add(new XYStruct{ vertexId = 10, x = 100, y = 20});
对于列表中的每个项,dx = 20
和dy = 10
都有一个增量
我想要获取当前顶点
右、下、右位置的项目的vertexId
例如,如果vertexId是0
,我想返回
Down vertex = 6
Right vertex = 1
Right Down Vertex = 7
I am trying
var right= myList.SingleOrDefault( v => v.x == myList[0].x + 20 && v.y == myList[0].y);
int resRight = right.vertexId;
var down= myList.SingleOrDefault( v => v.y == myList[0].y + 10 && v.x == myList[0].x );
int resDown = down.vertexId;
var downRight = myList.SingleOrDefault( v=> v.x == myList[0].x + 20 && v.y == myList[0].y + 10);
int resDownRight = downRight.vertexId;
是否有可能使这个查询更有效?
您可以构建类似于数据库索引的东西。例如,您可以使用一个额外的Dictionary。然后你可以很容易地通过使用字典[]-操作符来访问你的对象。
这将花费保持字典同步的努力,但如果列表变得非常大,它将节省大量时间。
你绝对确定你获得对象的标准是"唯一的"吗?如果列表中有多个条目匹配过滤器,SingleOrDefault将抛出异常。
如果使用字典,它将是这样的:
Dictionary<Int32, XYStruct> x_index = new Dictionary<int, XYStruct>();
Dictionary<Int32, XYStruct> y_index = new Dictionary<int, XYStruct>();
XYXYStruct s = new XYStruct { vertexId = 0, x = 0, y = 0 };
x_index.Add(s.x, s);
y_index.Add(s.y, s);
XYStruct item_by_x_index = x_index[0];
XYStruct item_by_y_index = y_index[0];
首先创建对象,然后将指向该对象的指针存储在两个字典中。
如果你想在两个值上有一个索引,你需要像
那样将字典"嵌套"到彼此之间。Dictionary<int, Dictionary<int, XYStruct>>
,但这样的结构体需要一些时间来实现。对于4k的对象,这可能有点过头了。
如果赋值x-coordinate => XYStruct不是唯一的,则需要使用类似
的东西。Dictionary<int, List<int, XYStruct>>
with非常接近你的"hashmap",除了它不散列。div;)
您的逻辑对我来说似乎是合理的(对于给定的约束),然而,您可以改进的地方很少,以获得性能和/或可读性。
- 有
Dictionary
代替List
来读取基于顶点的元素(直接)与O(1)
访问,或使用indexer
实现。 - 你确定你将为给定的搜索条件提供单个元素吗?如果没有,我建议使用
FirstOrDefault
。
Dictionary<int, XYStruct> points = ...;
int vertex =0; // specify position
var right= points.FirstOrDefault( v => v.x == points[vertex].x + 20 && v.y == points[vertex].y);
if(right != null)
{
int resRight = right.Value.vertexId;
}