【问题标题】:Initializing jagged arrays初始化锯齿状数组
【发布时间】:2010-12-16 21:00:57
【问题描述】:

我想在 C# 中创建数组 10 * 10 * 10,例如 int[][][](不是 int[,,])。

我会写代码:

int[][][] count = new int[10][][];

for (int i = 0; i < 10; i++) 
{
    count[i] = new int[10][];

    for (int j = 0; j < 10; j++)
        count[i][j] = new int[10];
}

但我正在寻找一种更漂亮的方式。可能是这样的:

int[][][] count = new int[10][10][10];

【问题讨论】:

    标签: c# .net jagged-arrays


    【解决方案1】:
    int[][][] my3DArray = CreateJaggedArray<int[][][]>(1, 2, 3);
    

    使用

    static T CreateJaggedArray<T>(params int[] lengths)
    {
        return (T)InitializeJaggedArray(typeof(T).GetElementType(), 0, lengths);
    }
    
    static object InitializeJaggedArray(Type type, int index, int[] lengths)
    {
        Array array = Array.CreateInstance(type, lengths[index]);
        Type elementType = type.GetElementType();
    
        if (elementType != null)
        {
            for (int i = 0; i < lengths[index]; i++)
            {
                array.SetValue(
                    InitializeJaggedArray(elementType, index + 1, lengths), i);
            }
        }
    
        return array;
    }
    

    【讨论】:

    • 有没有办法做到这一点,同时也将数组值设置为零以外的值?比如,-1?
    • 很好的答案,考虑得很好。
    • @metinoheat,我认为可以这样:if (elementType != null) { ... } else { for (int i = 0; i &lt; lengths[index]; i++) { array.SetValue(-1, i); } }
    【解决方案2】:

    你可以试试这个:

    int[][][] data = { new[] { new[] {1,2,3} }, new[] { new[] {1,2,3} } };

    或者没有明确的值:

    int[][][] data = { new[] { Enumerable.Range(1, 100).ToArray() }, new[] { Enumerable.Range(2, 100).ToArray() } };

    【讨论】:

    • 我想知道为什么这没有被投票...对于int以外的类型:double[] data = {new double[] {1, 4, 2}, new double[] {7, 4, 2,1, 0.66, 5.44}, new double[] {1.2345678521, 874347665423.12347234563233, 5e33, 66e234, 6785e34}};
    • 这是一个很好的答案,因为它完全依赖于内置语言。如果一个人想要简单地访问原始数据类型而不是编写太多样板文件,那就太好了。
    【解决方案3】:

    没有内置的方法来创建一个数组并在其中创建所有元素,因此它不会像您希望的那样简单。这将是尽可能多的工作。

    你可以创建一个方法来创建一个数组和其中的所有对象:

    public static T[] CreateArray<T>(int cnt, Func<T> itemCreator) {
      T[] result = new T[cnt];
      for (int i = 0; i < result.Length; i++) {
        result[i] = itemCreator();
      }
      return result;
    }
    

    然后你可以用它来创建一个三级锯齿数组:

    int[][][] count = CreateArray<int[][]>(10, () => CreateArray<int[]>(10, () => new int[10]));
    

    【讨论】:

      【解决方案4】:

      Linq

      的帮助下
      int[][][] count = new int[10][][].Select(t => new int[10][].Select(tt => new int[10]).ToArray()).ToArray();
      

      它确实不漂亮,可能也不快,但它是单线的。

      【讨论】:

        【解决方案5】:

        没有比编写 2 个 for 循环更“优雅”的方法了。这就是为什么它们被称为“锯齿状”,每个子阵列的大小可以变化。

        但这留下了一个问题:为什么不使用 [,,] 版本?

        【讨论】:

        • 多维数组被分配为一大块内存,锯齿状数组是独立的块——如果内存使用量很大,多维数组更容易导致OutOfMemoryException。访问锯齿状数组也更快(因为 CLR 针对 SZ 数组进行了优化 - 一维,从零开始)
        • thecoop,你在这两个方面都是对的,但两者都没有 size=10 甚至 100 多。但除此之外,它很快就会加起来。
        • @thecoop,您是否真的测试过您声称的内容?我很好奇。
        【解决方案6】:
        int[][][] count = Array.ConvertAll(new bool[10], x =>
                          Array.ConvertAll(new bool[10], y => new int[10]));
        

        【讨论】:

          【解决方案7】:

          3 维数组听起来像是创建自己的类的好例子。面向对象可以很漂亮。

          【讨论】:

            【解决方案8】:

            您可以使用具有相同数据表的数据集。这可能表现得像一个 3D 对象(xyz = 行、列、表)......但无论你做什么,你最终都会得到一些大的东西;您仍然需要考虑 1000 项。

            【讨论】:

              【解决方案9】:

              你为什么不试试这个?

              int[,,] count = new int[10, 10, 10]; // Multi-dimentional array.
              

              你发现这种表示有什么问题吗??

              【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-09
              • 2019-06-17
              • 2014-05-03
              • 2011-08-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多