How do you loop through a multidimensional array?

后端 未结 7 1396
陌清茗
陌清茗 2021-01-03 19:50
foreach (String s in arrayOfMessages)
{
    System.Console.WriteLine(s);
}

string[,] arrayOfMessages is being passed in as a parameter

7条回答
  •  一向
    一向 (楼主)
    2021-01-03 20:19

    It looks like you found an answer suitable for your problem, but since the title asks for a multidimensional array (which I read as 2 or more), and this is the first search result I got when searching for that, I'll add my solution:

    public static class MultidimensionalArrayExtensions
    {
        /// 
        /// Projects each element of a sequence into a new form by incorporating the element's index.
        /// 
        /// The type of the elements of the array.
        /// A sequence of values to invoke the action on.
        /// An action to apply to each source element; the second parameter of the function represents the index of the source element.
        public static void ForEach(this Array array, Action action)
        {
            var dimensionSizes = Enumerable.Range(0, array.Rank).Select(i => array.GetLength(i)).ToArray();
            ArrayForEach(dimensionSizes, action, new int[] { }, array);
        }
        private static void ArrayForEach(int[] dimensionSizes, Action action, int[] externalCoordinates, Array masterArray)
        {
            if (dimensionSizes.Length == 1)
                for (int i = 0; i < dimensionSizes[0]; i++)
                {
                    var globalCoordinates = externalCoordinates.Concat(new[] { i }).ToArray();
                    var value = (T)masterArray.GetValue(globalCoordinates);
                    action(value, globalCoordinates);
                }
            else
                for (int i = 0; i < dimensionSizes[0]; i++)
                    ArrayForEach(dimensionSizes.Skip(1).ToArray(), action, externalCoordinates.Concat(new[] { i }).ToArray(), masterArray);
        }
    
        public static void PopulateArray(this Array array, Func calculateElement)
        {
            array.ForEach((element, indexArray) => array.SetValue(calculateElement(indexArray), indexArray));
        }
    }
    

    Usage example:

    var foo = new string[,] { { "a", "b" }, { "c", "d" } };
    foo.ForEach((value, coords) => Console.WriteLine("(" + String.Join(", ", coords) + $")={value}"));
    // outputs:
    // (0, 0)=a
    // (0, 1)=b
    // (1, 0)=c
    // (1, 1)=d
    
    // Gives a 10d array where each element equals the sum of its coordinates:
    var bar = new int[4, 4, 4, 5, 6, 5, 4, 4, 4, 5];
    bar.PopulateArray(coords => coords.Sum());
    

    General idea is to recurse down through dimensions. I'm sure the functions won't win efficiency awards, but it works as a one-off initialiser for my lattice and comes with a nice-enough ForEach that exposes the values and indices. Main downside I haven't solved is getting it to automatically recognise T from the Array, so some caution is required when it comes to the type safety.

提交回复
热议问题