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

时间:2016-07-04 16:37:11

标签: c# linq loops

我有一个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

我正在尝试

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;

是否可以提高查询效率?

3 个答案:

答案 0 :(得分:1)

您可以构建类似于数据库索引的东西。 例如,您可以使用其他词典。然后,您可以使用distionarys [] -Operator轻松访问您的对象。

这会使efford花费你的词典同步,但如果列表变得非常大,它会节省很多时间。

你绝对肯定,你获得对象的标准是&#34;独特的&#34;?如果列表中的多个条目与您的过滤器匹配,SingleOrDefault将抛出异常。

答案 1 :(得分:0)

使用字典,它看起来像这样:

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];

首先创建对象,然后在两个dictionarys中存储指向它的指针。

如果你想要一个2个值的索引,你需要将Dictionarys“嵌套”在一起,如

Dictionary<int, Dictionary<int, XYStruct>>

但像这样的结构需要一段时间才能实现。对于4k物体,这可能是一种过度杀伤。

如果赋值x坐标=&gt; XYStruct不是唯一的,你需要使用像

这样的东西
Dictionary<int, List<int, XYStruct>>

然后非常接近你的“hashmap”,除了它没有哈希。 ;)

答案 2 :(得分:0)

您的逻辑对我来说似乎是合理的(对于给定的约束),但是,为了获得性能和/或可读性,您可以改进一些事情。

  1. 使用Dictionary而不是List来基于具有O(1)访问权限的顶点(直接)读取元素,或使用indexer实现。
  2. 您确定您对给定的搜索条件有单一元素吗?如果不是,我建议使用FirstOrDefault
  3. -

    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;
    }