从搜索满足条件c#的xy点列表中获得3个结果

本文关键字:列表 结果 3个 xy 满足 搜索 条件 | 更新日期: 2023-09-27 17:54:30

我有一个List of Structs,它包含Id,以及xy坐标的值:

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 = 20dy = 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;

是否有可能使这个查询更有效?

从搜索满足条件c#的xy点列表中获得3个结果

您可以构建类似于数据库索引的东西。例如,您可以使用一个额外的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;)

您的逻辑对我来说似乎是合理的(对于给定的约束),然而,您可以改进的地方很少,以获得性能和/或可读性。

  1. Dictionary代替List来读取基于顶点的元素(直接)与O(1)访问,或使用indexer实现。
  2. 你确定你将为给定的搜索条件提供单个元素吗?如果没有,我建议使用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;
}