初始化锯齿状数组

Posted

技术标签:

【中文标题】初始化锯齿状数组【英文标题】: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];

【问题讨论】:

【参考方案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.

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

【讨论】:

这是一个多维数组,不是一个锯齿状数组。见***.com/questions/597720/… 是的,我知道。我的问题是这种表示有什么问题。

以上是关于初始化锯齿状数组的主要内容,如果未能解决你的问题,请参考以下文章

csharp 如何声明,分配和初始化一维,多维和锯齿状数组的示例。

C/C++ 中是不是存在锯齿状数组?

C#二维数组的介绍

OSG消锯齿

如何通过 Emscripten 激活抗锯齿

C# 中锯齿状数组的内存分配与 C++ 中的二维数组内存分配