I need a cartesian product of 6 arrays - the catch is that at any time upto 5 arrays could be null. It works great when all arrays are populated but bombs when any of the arrays are null
my arrays are something like this
MatrixArray_1[0] = 1
MatrixArray_1[1] = 2
MatrixArray_2[0] = null
MatrixArray_2[1] = null
MatrixArray_n[0] = 2
MatrixArray_n[1] = 2
etc.
I am using this code currently...derived from http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
var product1 = from first in MatrixArray_1
from second in MatrixArray_2
from third in MatrixArray_3
from fourth in MatrixArray_4
from fifth in MatrixArray_5
from sixth in MatrixArray_6
select new[] { first, second, third, fourth, fifth, sixth };
string[][] myCombos_linq = product1.ToArray();
I have tried putting MatrixArray_n where first != null
but that stops at the first null array and does not read thru all the remaining arrays so my return array is always 0 rows even though array1 and array 3 are populated.
Change of code/logic anything is appreciated at this point in time! TIA
Since Eric's approach is to use an IEnumerable<IEnumerable<T>>
, you must be doing something like this:
Eric's code:
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] {item}));
}
Call site:
var sequences = new int?[][] { MatrixArray_1, MatrixArray_2, ..., MatrixArray_6 };
var cartesianSequence = sequences.CartesianProduct();
Change the call site:
var cartesianSequence = sequences.Where(a => a.Any(e => e != null)).CartesianProduct();
The Where call will exclude sequences where all elements are null.
To exclude null arrays as well as arrays containing only null values:
var cartesianSequence = sequences.Where(a => a != null && a.Any(e => e != null)).CartesianProduct();
Or, with query comprehension:
var filteredSequences =
from sequence in sequences
where sequence != null && sequence.Any(e => e != null)
select sequence
var cartesianSequence = filteredSequences.CartesianProduct();
EDIT
Another possibility is that you want to exclude null elements of each sequence, even if some elements are non-null:
var filteredSequences =
from sequence in sequences
where sequence != null && sequence.Any(e => e != null)
select (from v in sequence where v.HasValue select s)
var cartesianSequence = filteredSequences.CartesianProduct();
OR
var cartesianSequence = sequences
.Where(s => s != null && s.Any(e => e != null))
.Select(s => s.Where(v => v != null))
.CartesianProduct();
But it's hard to know exactly what to advise since we don't know what you're doing with the result.