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”之和小于和大于两个数字的所有组合,并且只保留那些 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 模式),因此调用此方法实际上不会执行任何计算。

现在我们可以在您的 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);
于 2013-05-08T16:19:28.727 回答