2009-11-15 3 views
12

Je souhaite créer un tableau 10 * 10 * 10 en C# comme int[][][] (et non int[,,]).Initialisation des tableaux dentelés

Je peux écrire le code:

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]; 
} 

mais je suis à la recherche d'une plus belle façon pour elle. Peut être quelque chose comme ça:

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

Répondre

20
int[][][] my3DArray = CreateJaggedArray<int[][][]>(1, 2, 3); 

utilisant

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

est-il un moyen de le faire tout en définissant les valeurs du tableau à quelque chose d'autre que zéro? comme dire, -1? – metinoheat

+0

Bonne réponse, vraiment bien pensé. – mafu

2

Un tableau tridimensionnel sonne comme un bon cas pour créer votre propre classe. Être orienté objet peut être beau.

0

Vous pouvez utiliser un ensemble de données avec des données identiques. Cela pourrait se comporter comme un objet 3D (xyz = ligne, colonne, table) ... Mais vous allez finir avec quelque chose de grand, peu importe ce que vous faites; vous devez toujours comptabiliser 1000 articles.

6

Il n'existe pas de méthode intégrée permettant de créer un tableau et de créer tous les éléments, ce qui ne va pas être aussi simple que vous le souhaiteriez. Ça va être autant de travail que c'est vraiment.

Vous pouvez faire une méthode pour créer un tableau et tous les objets qu'il contient:

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; 
} 

Ensuite, vous pouvez l'utiliser pour créer un tableau en dents de scie à trois niveaux:

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

Belle utilisation de définition générique récursif initions ... – thecoop

1

Il n'y a pas ' plus élégante que l'écriture des 2 boucles. C'est pourquoi ils sont appelés «déchiquetés», les tailles de chaque sous-groupe peuvent varier.

Mais cela laisse la question: pourquoi ne pas utiliser la version [,,]?

+3

Les tableaux multidimensionnels sont alloués comme un gros bloc de mémoire, les tableaux dentelés sont des blocs séparés - s'il y a beaucoup d'utilisation de la mémoire, le tableau multidimensionnel est plus susceptible de provoquer OutOfMemoryException. – thecoop

+0

thecoop, vous avez raison sur les deux points mais pas plus que la taille = 10, voire 100. Mais au-delà, ça s'additionne rapidement. –

+0

@thecoop, Avez-vous réellement ** testé ** ce que vous prétendez? Je suis curieux. – strager

7

Vous pouvez essayer ceci:

 

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

ou sans valeurs explicites:

 

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

Je me demande pourquoi cela n'est pas voté ... pour les types autres que 'int':' double [] data = {nouveau double [] {1, 4, 2}, nouveau double [] {7, 4, 2, 1, 0,66, 5,44}, nouveau double [] {1,2345678521, 874347665423,12347234563233, 5e33, 66e234, 6785e34}}; – Happypig375

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