【问题标题】:C#: convert nested list to nd-arrayC#:将嵌套列表转换为 nd 数组
【发布时间】:2020-10-06 06:47:32
【问题描述】:

我想将T 类型的嵌套列表(具有任意多个嵌套级别)转换为T 类型的多维数组

这与this 完全一样,但具有任意多个级别,这意味着递归。

如何用 C# 做到这一点?

我的类型是例如

List<List<List<List<int>>>>

并且期望int[][][][]int[,,,],最好是后者。

  • 这当然是假设每个同级列表的大小相同。

【问题讨论】:

  • int[][][][] 是一个 jagged 数组(数组数组的数组...),而不是 multidimension 一个 int[,,,]跨度>
  • @DmitryBychenko 已编辑。我不知道,我是从 python 来到 c# 的。我不介意哪个,但更喜欢多维的
  • 我会创建一个具有子属性的类并处理递归类等解决方案。

标签: c# arrays list nested type-conversion


【解决方案1】:

这是n维的解决方案。 我使用 MakeList() 为您的示例创建了一个 4 维的假列表 关键是首先找到维度及其大小,这在 CountDimensions 中完成。 此维度数组允许您使用 Array.CreateInstance 创建所需大小的数组 然后我通过创建一个以 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;
        }
    }
}

编辑:我最初为另一个解决方案留下了一个变量,现在被删除了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 2012-06-03
    • 2020-01-24
    • 1970-01-01
    • 2014-12-30
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多