使用LINQ从多维数组中提取特定值

Fre*_* F. 5 c# linq

我用的多dimentioned阵列工作bool,int以及各种struct.代码循环遍历这些数组并对特定值执行某些操作.例如,

        for (int x = 0; x < this.Size.Width; x++) {
            for (int y = 0; y < this.Size.Height; y++) {
                if (this.Map[x, y]) {
                    DrawTerrain(this.Tile[x, y].Location, Terrain.Water);
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

我可以做简单的LINQ,但我不能做我想做的事情.我想做的是使用LINQ.也许是这样的

from x in this.Map where x == true execute DrawTerrain(...)

但是,我不明白如何获取x和y位置或如何在LINQ语句中调用方法.

另外,如果我可以将此代码放入函数并且能够使用委托或谓词调用它,那将会很棒吗?我不知道委托或谓词是否正确.

    void Draw(Delegate draw, bool[,] map, struct[,] tiles) 
        from x in map where x == true draw(titles[x,y]).invoke;
    }
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 1

LINQ 查询语法并不是真正为处理二维数据结构而设计的,但您可以编写一个扩展方法,将二维数组转换为一系列值,其中包含原始二维数组中的坐标和来自二维数组的值。大批。您需要一个辅助类型来存储数据:

class CoordinateValue<T> {
  public T Value { get; set; }
  public int X { get; set; }
  public int Y { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样编写扩展方法(对于任何二维数组):

IEnumerable<CoordinateValue<T>> AsEnumerable(this T[,] arr) {
  for (int i = 0; i < arr.GetLength(0); i++)
    for (int j = 0; j < arr.GetLength(0); j++)
      yield new CoordinateValue<T> { Value = arr[i, j]; X = i; Y = j; };
}
Run Code Online (Sandbox Code Playgroud)

现在您终于可以开始使用 LINQ 了。要从 2D 数组中获取所有元素的坐标,以使元素中存储的值为true,可以使用以下命令:

var toDraw = from tile in this.Map.AsEnumerable()
             where tile.Value == true
             select tile;

// tile contains the coordinates (X, Y) and the original value (Value)
foreach(var tile in toDraw)
    FillTile(tile.X, tile.Y);
Run Code Online (Sandbox Code Playgroud)

这使您可以在过滤图块时指定一些有趣的条件。例如,如果您只想获取对角线元素,您可以编写:

var toDraw = from tile in this.Map.AsEnumerable()
             where tile.Value == true && tile.X == tile.Y
             select tile;
Run Code Online (Sandbox Code Playgroud)

要回答你的第二个问题 - 如果你想将行为封装到方法中,你可能需要使用一些Action<...>委托来表示将传递给该方法的绘图函数。但这取决于您的绘图方法的类型签名。