Nested foreach loops replacement in C#

By Mirek on (tags: c#, Join, categories: code)

Nested foreach loops is something that I have always felt uncomfortable with. Recently I have found out more elegant and in some cases even more efficient, replacement for nested double foreach loop.

Lets assume we have two lists of strings filled with some values
   1: var l1 = new List<string> { "A", "B", "C", ... };
   2: var l2 = new List<string> { "1", "2", "3", ... };

and we want to have a collection of all combinations of elements from list l1with elements from list l2.

Obvious solution comes naturally as nested double foreach loop

   1: var result = new List<string>();
   2: foreach (var x in l1)
   3:     foreach (var y in l2)
   4:         result.Add(x + y);

And here comes the replacement, I mentioned about, which is based on Join extension method.

   1: var result = l1.Join(l2, x => true, y => true, (x, y) => x + y).ToList();

The definition of Join method says that it correlates elements of two sequences based on matching keys. Since here we want to correlate each element with each element we fake the element’s key selector by returning true as a key for every element from both sequences.
Quick performance tests showed that in some cases foreach loop approach is faster, in other cases Join approach is faster, but there is one big advantage of using Join approach over foreach loop. In a test where each list has 10 thousand of integer numbers, the foreach loop approach crashes with OutOfMemory exception while the Join approach finishes in about 5 seconds. This is 10^8 iterations and apparently foreach loop allocates memory less efficiently than the Join method.
For the convenience the Combine extension method which uses the Join approach to combine elements from two collections

public static IEnumerable<TResult> Combine<T, TResult>(this IEnumerable<T> l1, IEnumerable<T> l2, Func<T, T, TResult> combineFunc)
{
     return l1.Join(l2, x => true, y => true, combineFunc);
}