C# 将二维数组上的两个循环转换为Linq语法
我有一个包含MyObj类型对象的二维数组 我想在传入匹配对象时从数组中获取索引。我想从这个数组中得到x和y值。我可以将这两个值作为采用x和y坐标的位置对象返回C# 将二维数组上的两个循环转换为Linq语法,c#,arrays,linq,C#,Arrays,Linq,我有一个包含MyObj类型对象的二维数组 我想在传入匹配对象时从数组中获取索引。我想从这个数组中得到x和y值。我可以将这两个值作为采用x和y坐标的位置对象返回 private Position GetIndices(MyObj obj) { for (int x = 0; x < myObjs.GetLength(0); x++) { for (int y = 0; y < myObjs.GetLength(1); y++) {
private Position GetIndices(MyObj obj)
{
for (int x = 0; x < myObjs.GetLength(0); x++)
{
for (int y = 0; y < myObjs.GetLength(1); y++)
{
if (myObjs[x, y] == obj)
{
return new Position(x, y);
}
}
}
}
是否有可能将此代码缩短为一些Linq代码行?但我不认为,它看起来很好:
var result = Enumerable.Range(0, myObjs.GetLength(0))
.Select(x => Enumerable.Range(0, myObjs.GetLength(1)).Select(y => new { x, y }))
.SelectMany(o => o)
.FirstOrDefault(o => myObjs[o.x, o.y] == obj);
但我不认为,它看起来很好:
var result = Enumerable.Range(0, myObjs.GetLength(0))
.Select(x => Enumerable.Range(0, myObjs.GetLength(1)).Select(y => new { x, y }))
.SelectMany(o => o)
.FirstOrDefault(o => myObjs[o.x, o.y] == obj);
如果你有兴趣,这里还有一个选择。它在第一个select中使用了一个索引器,并进行了一些计算,以找到该索引在二维数组中的位置
var o = new MyObj();
myObjs[1,2] = o;
var p = myObjs.Cast<MyObj>()
.Select((x,i) => Tuple.Create(x,i))
.Where(x => x.Item1 == o)
.Select(x => new Point(x.Item2 / myObjs.GetLength(1), x.Item2 % myObjs.GetLength(1)))
.SingleOrDefault();
Console.WriteLine(p); // prints {X=1,Y=2}
看起来你认为x坐标是数组的高度,y坐标是数组的宽度,在这种情况下,你需要稍微调高它:
var p = myObjs.Cast<MyObj>()
.Select((x,i) => Tuple.Create(x,i))
.Where(x => x.Item1 == o)
.Select(x => new Point(x.Item2 % myObjs.GetLength(1), x.Item2 / myObjs.GetLength(1)))
.SingleOrDefault();
Console.WriteLine(p); // prints {X=2,Y=1}
我使用Point而不是Position,因为它内置在.NET中,但您应该能够将一个替换为另一个。如果您感兴趣,这里还有另一个选项。它在第一个select中使用了一个索引器,并进行了一些计算,以找到该索引在二维数组中的位置
var o = new MyObj();
myObjs[1,2] = o;
var p = myObjs.Cast<MyObj>()
.Select((x,i) => Tuple.Create(x,i))
.Where(x => x.Item1 == o)
.Select(x => new Point(x.Item2 / myObjs.GetLength(1), x.Item2 % myObjs.GetLength(1)))
.SingleOrDefault();
Console.WriteLine(p); // prints {X=1,Y=2}
看起来你认为x坐标是数组的高度,y坐标是数组的宽度,在这种情况下,你需要稍微调高它:
var p = myObjs.Cast<MyObj>()
.Select((x,i) => Tuple.Create(x,i))
.Where(x => x.Item1 == o)
.Select(x => new Point(x.Item2 % myObjs.GetLength(1), x.Item2 / myObjs.GetLength(1)))
.SingleOrDefault();
Console.WriteLine(p); // prints {X=2,Y=1}
我使用Point而不是Position,因为它内置于.NET中,但您应该能够将一个点替换为另一个点。是的,这是可能的。您可以让Resharper为您执行到linq的作业循环。安装后,.是的,这是可能的。您可以让Resharper为您执行到linq的作业循环。安装后,.是的,不太好,从长远来看,传统的For/Foreach更具可读性。Linq被它的语法糖弄坏了:是的,不好,从长远来看,传统的For/Foreach更具可读性。Linq被它的语法糖弄得一团糟:这不是答案,只是建议使用一个工具将代码转换成Linq。问题是如果可能的话。答案是肯定的。这就是答案。还有一个解释是如何做到这一点:询问Resharper。没有人问代码应该是什么样子。这不是答案,只是建议使用一个工具将代码转换为LINQ。问题是如果可能的话。答案是肯定的。这就是答案。还有一个解释是如何做到这一点:询问Resharper。没有人问代码应该是什么样子。