我有一个包含MyObj
类型对象的二维数组。
private MyObj[,] myObjs = new MyObj[maxX, maxY];
我希望在传入匹配对象时从数组中获取索引。我想从这个数组中获取x和y值。我可以将这两个值作为Position
对象返回,该对象采用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++)
{
if (myObjs[x, y] == obj)
{
return new Position(x, y);
}
}
}
}
是否可以将此代码缩短为某些Linq代码行?
答案 0 :(得分:4)
但我不认为,它看起来不错:)
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);
答案 1 :(得分:1)
如果您有兴趣,可以选择其他选项。它在第一个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中,但您应该只能将一个交换为另一个。
答案 2 :(得分:0)
是的,这是可能的。您可以让Resharper为您完成工作(循环到linq)。安装完成后,just use the feature。