对于某些标签元素的坐标,我有2个点列表(List<Point>
)。一个列表用于之前,一个列表用于移动之后,因此索引引用相同的标签元素。我想比较具有相同索引的每个元素,看看哪些元素的点数发生了变化。
List<int> changedIndexes = new List<int>();
for(int i = 0; i < labelLocationsBefore.Count; i++)
{
if (labelLocationsBefore[i].X != labelLocationsAfter[i].X || labelLocationsBefore[i].Y != labelLocationsAfter[i].Y)
{
changedIndexes.Add(i);
}
}
这个循环的作用是什么。但是如何将其转换为Linq表达式并检索已更改的标签索引?
答案 0 :(得分:1)
您正在寻找Select
Func<T, int, bool>
方法,该方法需要changedIndexes = labelLocationsBefore
.Select((point,idx) => new { point, idx })
.Where(p => p.point.X != labelLocationsAfter[p.idx].X ||
p.point.Y != labelLocationsAfter[p.idx].Y)
.Select(p => p.idx)
.ToList();
,其中第二个参数是索引:
{{1}}
答案 1 :(得分:1)
一种选择是使用Enumerable.Zip
加入两个集合,然后使用Select
获取每个连接对的索引,然后进行适当过滤:
var changedIndexes = labelLocationsBefore
.Zip(labelLocationsAfter, (before, after) => before.Equals(after))
.Select((equal, index) => new { Moved = !equal, Index = index })
.Where(result => result.Moved)
.Select(result => result.Index)
.ToList();
这个片段有一些不错的属性(它基于表达式,易于阅读,没有重复),但由于需要生成,它必然比直接for
循环更麻烦且性能更差所有前后点的“移动?/索引”对 - 即使是那些只是确定它们没有被移动的那些也足以忽略它们。