For Each loop on a 2D array in VB.NET

You simply can’t. Multi-dimensional arrays aren’t really supported in the .NET framework infrastructure. They seem to be tagged on as an afterthought. The best solution is often not to use them, and to use jagged arrays instead (arrays of arrays – Integer()() instead of Integer(,)).


You can use Enumerable.Range recursively to iterate the dimensions of an array.

Lets say we have a two dimensional grid (rows and columns) of Int.

We can iterate it as follows:

using System.Linq;

[TestMethod]
public void TestTwoDimensionalEnumeration()
{
    int rowcount = 9;
    int columncount = 9;
    int[,] grid = new int[rowcount, columncount];
    var enumerated =
        Enumerable.Range(0, rowcount - 1).
        SelectMany(ri => Enumerable.Range(0, columncount - 1).
        Select(ci => new {
                            RowIndex = ri,
                            ColumnIndex = ci,
                            Value = grid[ri,ci]
                         }));
    foreach (var item in enumerated)
    {
        System.Diagnostics.Trace.WriteLine("Row:" + item.RowIndex + 
                                          ",Column:" + item.ColumnIndex + 
                                          ",Value:" + item.Value);
    }
}

The same logic can be applied to any number of dimensions.


You can accomplish this with nested For loops

Note: When using a For Each loop to iterate over elements in an array, the placeholder generated on each iteration is a copy of the value in the actual array. Changes to that value will not be reflected in the original array. If you want to do anything other than read the information you will need to use a For loop to address the array elements directly.

Assuming a two dimension array the following code example will assign a value to each element in each dimension.

Dim MasterIndex(5, 2) As String

For iOuter As Integer = MasterIndex.GetLowerBound(0) To MasterIndex.GetUpperBound(0)
  'iOuter represents the first dimension
  For iInner As Integer = MasterIndex.GetLowerBound(1) To MasterIndex.GetUpperBound(1)
    'iInner represents the second dimension
    MasterIndex(iOuter, iInner) = "This Isn't Nothing" 'Set the value
  Next 'iInner

  'If you are only interested in the first element you don't need the inner loop
  MasterIndex(iOuter, 0) = "This is the first element in the second dimension"
Next 'iOuter
'MasterIndex is now filled completely

You could optionally use the .Rank property to dynamically iterate over each dimension

If you want to loop over a jagged array like Konrad Rudolph was suggesting (This functionally more closely matches array implementations in other more loosely typed languages like PHP)you could go about it like so:

'This is a jagged array (array of arrays) populated with three arrays each with three elements
Dim JaggedIndex()() As String = {
  New String() {"1", "2", "3"},
  New String() {"1", "2", "3"},
  New String() {"1", "2", "3"}
}

For Each aOuter As String() In JaggedIndex
  'If you are only interested in the first element you don't need the inner for each loop
  Dim sDesiredValue As String = aOuter(0) 'This is the first element in the inner array (second dimension)

  For Each sElement As String In aOuter
    Dim sCatch As String = sElement 'Assign the value of each element in the inner array to sCatch
    sElement = "This Won't Stick" 'This will only hold value within the context of this loop iteration
  Next 'sElement
Next 'aOuter
'JaggedIndex is still the same as when it was declared