2009-11-15 13 views
12

Desidero creare un array 10 * 10 * 10 in C# come int[][][] (non int[,,]).Inizializzazione di matrici frastagliate

posso scrivere codice:

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

ma sto cercando un modo più bello per questo. Può essere qualcosa del genere:

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

risposta

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

utilizzando

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

c'è un modo per farlo mentre si impostano i valori dell'array su qualcosa di diverso da zero? come dire, -1? – metinoheat

+0

Ottima risposta, davvero ben pensata. – mafu

2

Un array tridimensionale suona come un buon caso per creare la propria classe. Essere orientati agli oggetti può essere bello.

0

È possibile utilizzare un set di dati con datatables identici. Questo potrebbe comportarsi come un oggetto 3D (xyz = riga, colonna, tabella) ... Ma finirai con qualcosa di grande, qualunque cosa tu faccia; devi ancora tenere conto di 1000 articoli.

6

Non esiste un modo integrato per creare un array e creare tutti gli elementi in esso, quindi non sarà nemmeno vicino alla semplicità che si vorrebbe che fosse. Sarà tanto lavoro quanto è realmente.

È possibile effettuare un metodo per la creazione di un array e tutti gli oggetti in essa contenuti:

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

quindi è possibile utilizzare che per creare una matrice irregolare a tre livelli:

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

Nizza uso di ricorsivo def generici initions ... – thecoop

1

non c'e ' modo più elegante di scrivere i 2 for-loops. Questo è il motivo per cui sono chiamati "frastagliati", le dimensioni di ciascun sotto-array possono variare.

Ma questo lascia la domanda: perché non usare la versione [,,]?

+3

Gli array multidimensionali sono allocati come un unico blocco di memoria, gli array frastagliati sono blocchi separati - se c'è un sacco di utilizzo della memoria, l'array multidimensionale ha maggiori probabilità di causare OutOfMemoryException. Anche l'accesso a un array frastagliato è più veloce (poiché il CLR è ottimizzato per gli array SZ - a dimensione singola, a base zero) – thecoop

+0

thecoop, hai ragione su entrambi i conteggi, ma nessuno dei due ha dimensioni pari a 10 o anche 100. Ma oltre a ciò, si aggiunge rapidamente. –

+0

@thecoop, hai effettivamente ** testato ** ciò che rivendichi? Sono curioso. – strager

7

si potrebbe provare questo:

 

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

o senza valori espliciti:

 

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

Mi chiedo perché questo non sia votato ... per tipi diversi da 'int':' double [] data = {new double [] {1, 4, 2}, new double [] {7, 4, 2, 1, 0.66, 5.44}, nuovo doppio [] {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]));