当您想像这样将逻辑链接在一起时,我认为您真的想使用 Linq。不幸的是,在多维数组上使用 Linq 可能很麻烦。但是,通过一些辅助方法,我们可以将数据数组转换为更有用的东西。首先,让我们为任何具有 3 个维度的对象构建一个包装类:
public class ThreeDimensionalArrayExtension<T> {
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
public T Value { get; set; }
}
接下来,让我们编写一个辅助方法,将 3 维数组转换为新类型的 IEnumerables:
public static class ThreeDimensionalArrayExtensionMethods {
public static IEnumerable<ThreeDimensionalArrayExtension<T>> ConvertArray<T>(this T[,,] foos) {
for(var x = 0; x < foos.GetLength(0); x++) {
for (var y = 0; y < foos.GetLength(1); y++) {
for (var z = 0; z < foos.GetLength(2); z++) {
yield return new ThreeDimensionalArrayExtension<T> { X = x, Y = y , Z = z, Value = foos[x, y, z] };
}
}
}
}
}
请注意,由于我们使用的是迭代器块(yield-return 模式),因此调用此方法实际上不会执行任何计算。
现在我们可以在您的 3 维数组上使用 Linq 的强大功能来过滤它!
myData.ConvertArray().Where(d => d.Value.Foo > 5)
.Where(d => IsPrime(d.Value.Foo))
.Where(...);
编辑:我看到您使用的是 3 个嵌套类,而不是我假设您使用的多维数组。目标应该仍然是将该对象转换为 IEnumerable,您可以在其上非常轻松地链接 Linq 查询以过滤或投影数据。在您的情况下,您可以执行以下操作:
public static class ThreeDimensionalArrayExtensionMethods {
public static IEnumerable<ThreeDimensionalArrayExtension<X>> ConvertArray(this X[] foos) {
for(var x = 0; x < foos.Count(); x++) {
for (var y = 0; y < foos[x].Count(); y++) {
for (var z = 0; z < foos[x][y].Count(); z++) {
yield return new ThreeDimensionalArrayExtension<T> { X = x, Y = y , Z = z, Value = foos[x][y][z] };
}
}
}
}
}
然后对 ConvertArray 使用相同的调用,然后使用上述过滤 Where 子句。
如果您不关心 X/Y/Z 索引,您也可以使用SelectMany
将多维列表投影到单维列表上:
X.SelectMany(y => y.SelectMany(z => z)).Where(z => z.Foo > 5);