Bookmark and Share

Fill a Multi-Dimensional Array

It is rare that I need to work directly with arrays in today’s world of LINQ to Objects. However, yesterday evening I found myself with the need to fill the elements of a multidimensional array. If I had any observers, I’m sure this would have been an amusing period of time as I struggled to find the correct iteration mechanism to set elements on a multi-dimensional array.

It’s quite easy when you’re working with a vector type (one dimension). You grab the array’s length, then iterate using a for loop setting each element using an indexer in the following manner: array[i] = value. In my case, I had a grid, so I needed to set array[x, y], and I wanted no assumptions about the size of the grid. In this case, the Length property will return the total number of elements in the array, so it is completely useless unless I wanted to take the square root. Somehow, taking the square root of the length didn’t seem correct, so I searched for the proper solution.

If the dimensions of an array are unknown, you must use the Rank property and the method GetLowerBound and GetUpperBound methods to properly work with it. I came up with an extension method that will fill dimensional arrays (not jagged) with the result of a function you pass in by iterating each element and passing the indices back to a function for calculation.

public static class ArrayExtensions
{
    public static void Fill<T>(this Array array, Func<int[], T> func)
    {
        var indices = new int[array.Rank];
        array.Fill(indices, 0, func);
    }

    private static void Fill<T>(this Array array, int[] indices, int rank, 
        Func<int[], T> func)
    {
        for (int index = array.GetLowerBound(rank); index <= array.GetUpperBound(rank); 
            index++)
        {
            indices[rank] = index;

            if (rank < array.Rank - 1)
            {
                array.Fill(indices, rank + 1, func);
            }
            else
            {
                array.SetValue(func(indices), indices);
            }
        }
    }
}

Here’s an example of how you can use the extension method.

var array = new int[5, 5, 5];
array.Fill(indices => indices.Sum());

The example simply creates a 5x5x5 cube and fills it with the sum of the indices at each elements location. The power in this is that we’ve encapsulated the complexity of iterating a multi-dimensional array in a method, then we accepted a function parameter so the caller of the method has power over what actually occurs within the encapsulated method. There is no need to write this same piece of code over and over.

blog comments powered by Disqus

KodefuGuru.GetInfo()

Chris Eargle
LinkedIn Twitter Technorati Facebook

Chris Eargle
Telerik Developer Evangelist, C# MVP

JustCode

Telerik .NET Ninja

 

INETA Community Speakers Program

 

MVP - Visual C#

 

Friend of RedGate

World Map

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.