代码之家  ›  专栏  ›  技术社区  ›  koryakinp

未知维数组上的C#循环

  •  2
  • koryakinp  · 技术社区  · 6 年前

    我想创建一个扩展方法来循环 System.Array 维数未知

    现在我用的是一种幼稚的方法:

    public static void ForEach<T>(this Array source, Action<T> action)
    {
        if(source.Rank == 1)
        {
            for (int w = 0; w < source.GetLength(0); w++)
            {
                action((T)source.GetValue(w));
            }
        }
        else if(source.Rank == 2)
        {
            for (int h = 0; h < source.GetLength(1); h++)
            {
                for (int w = 0; w < source.GetLength(0); w++)
                {
                    action((T)source.GetValue(h, w));
                }
            }
        }
        else if(source.Rank == 3)
        {
            // etc
        }
    }
    

    3 回复  |  直到 6 年前
        1
  •  1
  •   John Wu    6 年前

    如果不关心索引,只需在 System.Array 完全不知道它的等级。枚举器将命中每个元素。

    public class Program
    {
        public static void IterateOverArray(System.Array a)
        {
            foreach (var i in a)
            {
                Console.WriteLine(i);
            }
        }
    
        public static void Main()
        {
            var tests = new System.Array []
            {
                new int[] {1,2,3,4,5,6,7,8},
                new int[,]
                {
                    {1,2},{3,4},{5,6},{7,8}
                },
                new int[,,]
                {
                    {  {1,2},{3,4} },
                    {  {5,6},{7,8} }
                }
            };
    
    
            foreach (var t in tests)
            {
                Console.WriteLine("Dumping array with rank {0} to console.", t.Rank);
                IterateOverArray(t);
            }
        }
    }
    

    输出:

    Dumping array with rank 1 to console.
    1
    2
    3
    4
    5
    6
    7
    8
    Dumping array with rank 2 to console.
    1
    2
    3
    4
    5
    6
    7
    8
    Dumping array with rank 3 to console.
    1
    2
    3
    4
    5
    6
    7
    8
    

    Link to DotNetFiddle example

        2
  •  1
  •   TheGeneral    6 年前

    foreach 利用 yield

    public static IEnumerable<T> GetRank<T>(this Array source,int dimension, params int[] indexes )
    {
    
       var indexList = indexes.ToList();
       indexList.Insert(dimension, 0);
       indexes = indexList.ToArray();
    
       for (var i = 0; i < source.GetLength(dimension); i++)
       {
          indexes[dimension] = i;
          yield return (T)source.GetValue(indexes);
       }
    }
    

    用法

    var test1 = new int[2, 2, 3];
    test1[1, 1, 0] = 1;
    test1[1, 1, 1] = 2;
    test1[1, 1, 2] = 3;
    foreach (var item in test1.GetRank<int>(2,1,1))
    {
      Console.WriteLine(item);
    }
    

    输出

    1
    2
    3
    

    Full demo here

        3
  •  -1
  •   zcleghern    6 年前