views:

82

answers:

2

I'm having a little trouble figuring out how to call the Parallel.ForEach with a 2D array of strings:

string[,] board = new string[,]{
        {"A", "B", "C", "D", "E" },
        {"F", "G", "H", "I", "J"},
        {"K", "L", "M", "N", "O"},
        {"0", "1", "2", "3", "4"}};

Parallel.ForEach(board, row =>
    {
        for (int i = 0; i < row.Length; ++i)
        {
            // find all valid sequences
        }
    });

If I don't specify the type explicitly I get the following error:

The type arguments for method 'System.Threading.Tasks.Parallel.ForEach(System.Collections.Generic.IEnumerable, System.Action)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

What's the proper way to specify the type arguments explicitly?

+6  A: 

The problem for you is that 2-dimensional arrays do not implement IEnumerable<one-dimensional-array>. (It does implement IEnumerable, but it's an IEnumerable of strings that "flattens" the array.) You can do two things:

  • Change the string[,] to a jagged array-of-arrays, string[][].

  • Implement your own extension method that iterates over a two-dimensional array and turns it into an IEnumerable<one-dimensional-array>.

mquander
Ahh... the *jagged* array worked!
Lirik
@Link: Plus, if performance is enough concern to paralleize this you would want to use jagged arrays anyway because they more efficient to index into.
Brian Gideon
@Brian Gideon: I think that's a pretty strange thing to say. Parallelization, where appropriate (e.g., in the case of long-running, independent operations), can make a *substantial* change in performance. Converting a multi-dimensional array to a jagged array for performance reasons is what I'd call a micro-optimization.
Dan Tao
@Dan: Maybe, but indexing a 2D jagged array is about 3x faster than indexing a multidimensional array. Sure, if indexing is not the dominating factor in the algorithm it buys you little, but if it is then it could wind up being faster than parallelizing the multidimensional array version. Either way it is such as easy change to make and has so few (if any) consequences on code readability or maintainability that it almost seems obvious. Of course any optimization that still keeps you in the same Big-Oh complexity class could qualify as a micro-optimization...`Parallel.For` included.
Brian Gideon
+3  A: 

You should still be able to make this work with a multi-dimensional array, just using Parallel.For instead of Parallel.ForEach:

string[,] board = new string[,] {
    {"A", "B", "C", "D", "E" },
    {"F", "G", "H", "I", "J"},
    {"K", "L", "M", "N", "O"},
    {"0", "1", "2", "3", "4"}
};

int height = board.GetLength(0);
int width = board.GetLength(1);

Parallel.For(0, height, y =>
    {
        for (int x = 0; x < width; ++x)
        {
            string value = board[y, x];
            // do whatever you need to do here
        }
    }
);
Dan Tao
@Dan, that's good idea too! Thanks!
Lirik