2

我试图能够通过锯齿状数组运行,但数组深度不是恒定的。我正在寻找一种干净的方式来遍历数组中的每个对象。现在我有一个简单的 switch 案例,可以通过将其 Rank 作为案例的 int 来处理不同的级别。

但有时阵列深 2 层,有时深 5 层。我不想为每个深度级别写一个案例。

例如,我有一个名为 myObj 的对象,有时它是 myObj[] 或 myObj[][] 或 myObj[][][][];

使用 foreach 或 IEnumerator 仅遍历数组的第一个维度

4

4 回答 4

4

这是一种遍历锯齿状/多维数组的扩展方法(类似于 David B. one's 但具有产量、空值处理和类型转换):

public static class Extensions
{
    public static IEnumerable<T> Traverse<T>(this Array array)
    {
        foreach (object val in array)
        {
            if (val == null)
                continue; //null means empty sub-array --> skip it
            if (val is Array)
            {
                var subArray = (Array)val;
                foreach (var value in subArray.Traverse<T>())
                    yield return value;
            }
            else
            {
                yield return (T)val;
            }
        }
    }
}

使用示例:

class Program
{
    static void Main(string[] args)
    {
        int[][][] jagged = new int[4][][];

        jagged[0] = new int[2][] { new[] { 0, 1 }, new[] { 2, 3, 4 } };
        jagged[1] = new int[3][] { new[] { 5, 6, 7 }, new[] { 8, 9, 10 }, new[] { 11, 12 } };
        jagged[3] = new int[4][] { new[] { 13, 14 }, null, new[] { 15, }, new[] { 16 } };

        var jaggedElements = jagged.Traverse<int>().ToList();
        // contains:  1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

       int[, ,] multi = new[, ,] { { { 1, 2 }, { 3, 4 } },
                        { { 4, 5 }, { 6, 7 } }, 
                        { { 8, 9 }, { 10, 11 } } };


       var multiElements = multi.Traverse<int>().ToList();
       // contains:  1,2,3,4,5,6,7,8,9,10,11

    }
}
于 2011-02-03T16:07:37.653 回答
3

这应该这样做。. .

private static void EnumerateObjects(Array items)
{
    foreach (var item in items)
    {
        if (item is Array)
        {
            EnumerateObjects((Array)item);
        }
        else if (item is MyObject)
        {
            Console.WriteLine(item);
        }
    }
}
于 2011-02-03T15:53:22.493 回答
1

像这样的东西?

    static void Main(string[] args)
    {
        int[][][] x = new int[][][]
        {
            new int[][]
            {
                new int [] { 1, 2, 3, 4 },
                new int [] { 5, 6 },
                new int [] { 7 }
            },
            new int[][]
            {
                new int [] { 8 },
                new int [] { 9, 10 },
                new int [] { 11, 12, 13, 14 }
            }
        };

        DeepEnumerateArray(x);
        Console.ReadLine();
    }

    static void DeepEnumerateArray(Array x)
    {
        if (x.Length == 0)
            return;

        object first = x.GetValue(0);
        if (first is Array)
        {
            foreach (Array y in x)
                DeepEnumerateArray(y);
        }
        else
        {
            foreach (object z in x)
                Console.WriteLine(z);
        }
    }
于 2011-02-03T15:45:37.393 回答
0

你的答案是递归。我认为这行不通。如果您有一个带有子集合的类,它会起作用。

int main()
{
    CheckObj(myObject, 0);
}

void CheckObj(object myObject, int level)
{
    if(!(myObject is myObj[]))
    {
        foreach(myObj[] o in (myObj[][])myObject)
        {
            CheckObj(o, level + 1);
        }
    }
    else
    {
        //do what you need to do with myObj[]
    }
}
于 2011-02-03T15:41:01.013 回答