Хотя эта проблема на первый взгляд кажется простой, на самом деле она сложнее, чем кажется. Однако, признавая, что посещение каждой позиции в многомерном (или даже зубчатом) массиве является декартовым произведениемоперация на множестве индексов массива - мы можем упростить решение ... и в конечном итоге написать более элегантное решение.
Мы собираемся использовать LINQ Эрика ЛиппертаДекартовой продукт реализация для выполнения тяжелой работы. Вы можете прочитать больше о том, как это работает, в его блоге, если хотите.
Хотя эта реализация предназначена для посещения ячеек многомерного массива -должно быть относительно легко увидеть, как расширить его, чтобы посетить также зубчатый массив.
public static class EnumerableExt
{
// Eric Lippert's Cartesian Product operator...
public 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 }));
}
}
class MDFill
{
public static void Main()
{
// create an arbitrary multidimensional array
Array mdArray = new int[2,3,4,5];
// create a sequences of sequences representing all of the possible
// index positions of each dimension within the MD-array
var dimensionBounds =
Enumerable.Range(0, mdArray.Rank)
.Select(x => Enumerable.Range(mdArray.GetLowerBound(x),
mdArray.GetUpperBound(x) - mdArray.GetLowerBound(x)+1));
// use the cartesian product to visit every permutation of indexes
// in the MD array and set each position to a specific value...
int someValue = 100;
foreach( var indexSet in dimensionBounds.CartesianProduct() )
{
mdArray.SetValue( someValue, indexSet.ToArray() );
}
}
}
Теперь тривиально выделить этот код в метод многократного использования, который можно использовать как для зубчатых, так и для многомерных массивов.... или любую структуру данных, которую можно рассматривать как прямоугольный массив.