Linq抓住点的左上角,不包括第一行和第一列

时间:2018-08-29 17:58:58

标签: c# linq

我想获取点列表的左上角和右上角。我可以这样获得左上和右上:

var topRightPoint = points.OrderBy(pnt => pnt.Y).ThenByDescending(pnt => pnt.X).FirstOrDefault();
var topLeftPoint = points.OrderBy(pnt => pnt.X).ThenBy(pnt => pnt.Y).FirstOrDefault();

但是我要抓住的是一行中一列的点,如下所示  绿色圆圈指出: enter image description here

我尝试在orderby之后,thenbydescending / thenby之后执行跳过操作,但是没有给出我期望的行为:

var topRightPoint = centerPoints.OrderBy(pnt => pnt.Y).Take(1).OrderBy(pnt => pnt.Y).ThenByDescending(pnt => pnt.X).Take(1).FirstOrDefault();

此外,我不知道有多少行或列。我得到的只是图像。

我还希望左下角和右下角,删除一个列/行。因此,我要针对的是可以在任何时候使用的通用解决方案。

2 个答案:

答案 0 :(得分:1)

如果按一个坐标对点进行分组,则可以排序并跳过整个第一个坐标,例如排并取得下一行,按另一个坐标排序,并取得下一个到最后一点:

var topRightIn1 = points.GroupBy(p => p.Y).OrderBy(pg => pg.Key).Skip(1).First().OrderByDescending(p => p.X).Skip(1).First();
var topLeftIn1 = points.GroupBy(p => p.Y).OrderBy(pg => pg.Key).Skip(1).First().OrderBy(p => p.X).Skip(1).First();

var bottomRightIn1 = points.GroupBy(p => p.Y).OrderByDescending(pg => pg.Key).Skip(1).First().OrderByDescending(p => p.X).Skip(1).First();
var bottomLeftIn1 = points.GroupBy(p => p.Y).OrderByDescending(pg => pg.Key).Skip(1).First().OrderBy(p => p.X).Skip(1).First();

您可以将其包装在一个函数中,该函数根据您想要的角添加OrderByOrderByDescending,但我不确定是否值得。

答案 1 :(得分:0)

要选择最高点,请使用OrderByDescending 要选择最低点,请使用OrderBy 要选择比最高点少1点的值,请使用OrderByDescending和Skip(1) 要选择比最低点高1点的价格,请使用OrderBy和Skip(1)

对于右上角 最高X-1,最低Y + 1

var topRightPoint = centerPoints.OrderByDescending(pnt => pnt.X).Skip(1).First().OrderBy(pnt => pnt.Y).Skip(1).First();

对于左上方 最低X +1,最低Y + 1

var topLeftPoint = centerPoints.OrderBy(pnt => pnt.X).Skip(1).First().OrderBy(pnt => pnt.Y).Skip(1).First();

左下角和右下角类似