このようにロジックを連鎖させたいときは、どうしても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 パターン) を使用しているため、このメソッドを呼び出しても実際には計算は実行されないことに注意してください。
これで、Linq の機能を 3 次元配列で使用して、必要に応じてフィルター処理できるようになりました。
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
、多次元リストを 1 次元リストに射影するために使用することもできます。
X.SelectMany(y => y.SelectMany(z => z)).Where(z => z.Foo > 5);