0

これは説明が難しい!申し訳ありませんが、これは... [X][Y][Z]のデータの3D配列を持っていて、10種類ほどの組み合わせ条件をチェックして、一致した場合のデータのみを保持するのが好きです...例:

              X         Y      Z
//myData[1..1000000][1..10][1..10].foo // foo is an int

X[i].Y[ii].Z[iii].foo; // X is a container, Y= 1 to 10 levels. And Z= objects

//I want to apply a "filter" to the Z objects... 

「foo」の合計が 2 つの数値よりも小さい場合と大きい場合のすべての組み合わせを検索し、それらの Z オブジェクトのみを保持するとします。

次の反復では、「foo」が素数である場所だけを見つけて、Zオブジェクトのみを保持したい

条件が増えると、リストはどんどん小さくなります。それらが実行される順序は重要ではありません。私はそれを行う方法を知っていますが、いくつかの本当に厄介なループに陥ってしまいます... 何かアイデアはありますか? 元のリストから削除するよりも、別のリストに追加する方が速いのではないでしょうか? 前もって感謝します!

4

1 に答える 1

2

このようにロジックを連鎖させたいときは、どうしても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);
于 2013-05-08T16:19:28.727 に答える