Инициализация зубчатых массивов

Я хочу создать массив 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;
}

Ответ 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()
    }
};

Ответ 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

Трехмерный массив звучит как хороший пример для создания собственного класса. Быть объектно ориентированным может быть красивым.

Ответ 5

Нет более "более элегантного" способа, чем писать 2 цикла for. Вот почему они называются "зубчатыми", размеры каждого поддиапазона могут варьироваться.

Но это оставляет вопрос: почему бы не использовать версию [,]?

Ответ 6

int[][][] count = Array.ConvertAll(new bool[10], x =>
                  Array.ConvertAll(new bool[10], y => new int[10]));

Ответ 7

Вы можете использовать набор данных с идентичными данными. Это может вести себя как 3D-объект (xyz = строка, столбец, таблица)... Но у вас будет что-то большое, независимо от того, что вы делаете; вам все равно придется учитывать 1000 предметов.

Ответ 8

С небольшой помощью от Linq

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

Это конечно не красиво и, вероятно, не быстро, но это одна строка.

Ответ 9

Почему бы тебе не попробовать это?

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

Любая проблема, которую вы видите с этим видом представления?