使用 linq 查找锯齿状数组中最左边和最右边的点?
Using linq to find the leftmost and rightmost point in a jagged array?
我确定它在某处,但我找不到它。
我有一个标准
StrokeCollection strokes
集合中的每个笔划都由一个点数组组成。因此,这是锯齿状的点数组,Point[][]
我需要找到 StrokeCollection 中最左边和最右边的点。这是如何用 linq 完成的?
这基本上就是我正在尝试做的(没有成功):
var x = from stroke in strokes
from point in stroke
where min(point.x)
select point
如有任何帮助,我们将不胜感激。
编辑:显然直接使用墨水笔点存在一些问题,所以让
Point[][] myStrokeCollection = new Point[strokes.Count][];
for (int i = 0; i < strokes.Count; i++)
{
// creating a one-dimensional array of StylusPoints for the i row of myStrokeCollection.
myStrokeCollection[i] = new Point[strokes[i].StylusPoints.Count];
for (int j = 0; j < strokes[i].StylusPoints.Count; j++)
{
myStrokeCollection[i][j] = new Point();
myStrokeCollection[i][j].X = strokes[i].StylusPoints[j].X;
myStrokeCollection[i][j].Y = strokes[i].StylusPoints[j].Y;
}
}
对于 myStrokeCollection ,最左边的点 (x,y) 和最右边的点 (x,y) 是否可以通过 linq 获得(一次通过?)? (希望没有定义其他类型)。
(from stroke in strokeCollection
from point in stroke
group point by 1 into g
select new { Left = g.Min (p => p.x), Right = g.Max (p => p.x)}).FirstOrDefault();
Here is what needs to be done
var leftMostVal = strokeCollection.Min(p => p.Point.Min(q => q.Min(r => r.X)));
var rightMostVal = strokeCollection.Max(p => p.Point.Max(q => q.Max(r => r.X)));
Here is fiddle https://dotnetfiddle.net/y5hZ7w
Or
public class StrokeCollection : List<Stroke>
{
}
public class Stroke : List<Point>
{
public Point[][] Points { get; set; }
}
class Program
{
static void Main(string[] args)
{
StrokeCollection lst = new StrokeCollection();
Random rnd1 = new Random(3);
Random rnd2 = new Random(13);
for (int i = 0; i < 10; i++)
{
int x = rnd1.Next(1, 5);
var s = new Stroke { Points = new Point[x][] };
foreach (var r in Enumerable.Range(0, x))
{
int y = rnd1.Next(1, 5);
s.Points[r] = new Point[y];
for (int j = 0; j < y; j++)
s.Points[r][j] = new Point(rnd2.Next(-50, 80), rnd2.Next(-20, 20));
}
lst.Add(s);
}
Point leftMostPoint = Point.Empty;
Point rightMostPoint = Point.Empty;
lst.ForEach(p1 =>
{
foreach (Point[] p2 in p1.Points)
{
foreach (var p3 in p2)
{
if (leftMostPoint == Point.Empty)
leftMostPoint = p3;
if (rightMostPoint == Point.Empty)
rightMostPoint = p3;
if (p3.X < leftMostPoint.X)
leftMostPoint = p3;
if (p3.X > rightMostPoint.X)
rightMostPoint = p3;
}
}
});
Console.WriteLine("Leftmost point " + leftMostPoint.ToString());
Console.WriteLine("Rightmost point " + rightMostPoint.ToString());
}
}
编辑:更新这是您最终需要的
System.Windows.Ink.StrokeCollection strokeCollection; //Set it to whatever resultant you want collection to set
var l1 = strokeCollection.SelectMany(p => p.StylusPoints)
.GroupBy(p => p.X)
.OrderBy(p => p.Key)
.ToList();
StylusPoint leftPoint = l1.First().FirstOrDefault();
StylusPoint rightPoint = l1.Last().FirstOrDefault();
来自聊天中的 Sangram,效果很好:
var l1 = strokeCollection.SelectMany(p => p.StylusPoints)
.GroupBy(p => p.X)
.OrderBy(p => p.Key)
.ToList();
StylusPoint leftPoint = l1.First().FirstOrDefault();
StylusPoint rightPoint = l1.Last().FirstOrDefault();
我确定它在某处,但我找不到它。
我有一个标准
StrokeCollection strokes
集合中的每个笔划都由一个点数组组成。因此,这是锯齿状的点数组,Point[][]
我需要找到 StrokeCollection 中最左边和最右边的点。这是如何用 linq 完成的?
这基本上就是我正在尝试做的(没有成功):
var x = from stroke in strokes
from point in stroke
where min(point.x)
select point
如有任何帮助,我们将不胜感激。
编辑:显然直接使用墨水笔点存在一些问题,所以让
Point[][] myStrokeCollection = new Point[strokes.Count][];
for (int i = 0; i < strokes.Count; i++)
{
// creating a one-dimensional array of StylusPoints for the i row of myStrokeCollection.
myStrokeCollection[i] = new Point[strokes[i].StylusPoints.Count];
for (int j = 0; j < strokes[i].StylusPoints.Count; j++)
{
myStrokeCollection[i][j] = new Point();
myStrokeCollection[i][j].X = strokes[i].StylusPoints[j].X;
myStrokeCollection[i][j].Y = strokes[i].StylusPoints[j].Y;
}
}
对于 myStrokeCollection ,最左边的点 (x,y) 和最右边的点 (x,y) 是否可以通过 linq 获得(一次通过?)? (希望没有定义其他类型)。
(from stroke in strokeCollection
from point in stroke
group point by 1 into g
select new { Left = g.Min (p => p.x), Right = g.Max (p => p.x)}).FirstOrDefault();
Here is what needs to be done
var leftMostVal = strokeCollection.Min(p => p.Point.Min(q => q.Min(r => r.X)));
var rightMostVal = strokeCollection.Max(p => p.Point.Max(q => q.Max(r => r.X)));
Here is fiddle https://dotnetfiddle.net/y5hZ7w
Or
public class StrokeCollection : List<Stroke>
{
}
public class Stroke : List<Point>
{
public Point[][] Points { get; set; }
}
class Program
{
static void Main(string[] args)
{
StrokeCollection lst = new StrokeCollection();
Random rnd1 = new Random(3);
Random rnd2 = new Random(13);
for (int i = 0; i < 10; i++)
{
int x = rnd1.Next(1, 5);
var s = new Stroke { Points = new Point[x][] };
foreach (var r in Enumerable.Range(0, x))
{
int y = rnd1.Next(1, 5);
s.Points[r] = new Point[y];
for (int j = 0; j < y; j++)
s.Points[r][j] = new Point(rnd2.Next(-50, 80), rnd2.Next(-20, 20));
}
lst.Add(s);
}
Point leftMostPoint = Point.Empty;
Point rightMostPoint = Point.Empty;
lst.ForEach(p1 =>
{
foreach (Point[] p2 in p1.Points)
{
foreach (var p3 in p2)
{
if (leftMostPoint == Point.Empty)
leftMostPoint = p3;
if (rightMostPoint == Point.Empty)
rightMostPoint = p3;
if (p3.X < leftMostPoint.X)
leftMostPoint = p3;
if (p3.X > rightMostPoint.X)
rightMostPoint = p3;
}
}
});
Console.WriteLine("Leftmost point " + leftMostPoint.ToString());
Console.WriteLine("Rightmost point " + rightMostPoint.ToString());
}
}
编辑:更新这是您最终需要的
System.Windows.Ink.StrokeCollection strokeCollection; //Set it to whatever resultant you want collection to set
var l1 = strokeCollection.SelectMany(p => p.StylusPoints)
.GroupBy(p => p.X)
.OrderBy(p => p.Key)
.ToList();
StylusPoint leftPoint = l1.First().FirstOrDefault();
StylusPoint rightPoint = l1.Last().FirstOrDefault();
来自聊天中的 Sangram,效果很好:
var l1 = strokeCollection.SelectMany(p => p.StylusPoints)
.GroupBy(p => p.X)
.OrderBy(p => p.Key)
.ToList();
StylusPoint leftPoint = l1.First().FirstOrDefault();
StylusPoint rightPoint = l1.Last().FirstOrDefault();