Вот решение для n измерений. Я создаю фальшивый список из 4 измерений для вашего примера с помощью MakeList (). Ключ должен сначала найти размеры и их размер, что делается в CountDimensions. Этот массив измерений позволяет вам создать массив нужного размера с помощью Array.CreateInstance. Затем I l oop по всем значениям, создавая массив индексов, который увеличивается 1 на 1 и распространяется на следующие измерения, когда одно из них заполнено. Тот же массив индексов используется для просмотра списков с помощью рекурсии с помощью GetListValue.
Вероятно, это не оптимально для производительности, но должно дать вам начало.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace NestedList
{
public class ListToArray
{
public Array Convert(IList input)
{
var dimensions = CountDimensions(input).ToArray();
var result = Array.CreateInstance(typeof(int), dimensions);
var indexes = new int[dimensions.Length];
while (indexes[0] < dimensions[0])
{
var currentValue = GetListValue(input, indexes, 0);
result.SetValue(currentValue, indexes);
// Inc last index, propagate to higher if needed
IncrementIndex(indexes, dimensions);
}
return result;
}
private int GetListValue(IList input, int[] indexes, int depth)
{
if (input[indexes[depth]] is IList sublist)
{
return GetListValue(sublist, indexes, depth + 1);
}
return (int)input[indexes[depth]];
}
private void IncrementIndex(int[] indexes, int[] dimensions)
{
var iIndex = indexes.Length - 1;
indexes[iIndex] = indexes[iIndex] + 1;
while (iIndex > 0 && indexes[iIndex] > dimensions[iIndex]-1)
{
indexes[iIndex] = 0;
iIndex--;
indexes[iIndex] = indexes[iIndex] + 1;
}
}
private IEnumerable<int> CountDimensions(IList input)
{
yield return input.Count;
if (input.Count > 0 && input[0] is IList sublist)
{
foreach (var value in CountDimensions(sublist))
{
yield return value;
}
}
yield break;
}
}
public class Program
{
static void Main()
{
var dec = new ListToArray();
var array = dec.Convert(MakeList());
}
private static List<List<List<List<int>>>> MakeList()
{
const int dim1 = 3;
const int dim2 = 4;
const int dim3 = 2;
const int dim4 = 5;
var nextValue = 0;
var dim1List = new List<List<List<List<int>>>>();
for (var x1 = 0; x1 < dim1; ++x1)
{
var dim2List = new List<List<List<int>>>();
for (var x2 = 0; x2 < dim2; ++x2)
{
var dim3List = new List<List<int>>();
for (var x3 = 0; x3 < dim3; ++x3)
{
var dim4List = new List<int>();
for (var x4 = 0; x4 < dim4; ++x4)
{
var element4 = nextValue++;
dim4List.Add(element4);
}
dim3List.Add(dim4List);
}
dim2List.Add(dim3List);
}
dim1List.Add(dim2List);
}
return dim1List;
}
}
}
Изменить: I изначально оставил переменную для другого решения, теперь удален.