2009-11-15 5 views
12

Ich möchte Array 10 * 10 * 10 in C# wie int[][][] (nicht int[,,]) erstellen.Initialization gezackte Arrays

Ich kann Code schreiben:

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

aber ich bin auf der Suche nach einem schöneren Weg für sie. Kann etwas in der Art sein:

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

Antwort

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

mit

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

gibt es eine Möglichkeit, dies zu tun, während auch die Array-Werte auf etwas anderes als Null setzen? wie gesagt, -1? – metinoheat

+0

Große Antwort, wirklich gut gedacht. – mafu

2

Ein dreidimensionales Array klingt wie ein guter Fall für die Erstellung Ihrer eigenen Klasse. Objektorientiert zu sein kann schön sein.

0

Sie könnten ein Dataset mit identischen Datentabellen verwenden. Das könnte sich wie ein 3D-Objekt verhalten (xyz = Zeile, Spalte, Tabelle) ... Aber du wirst mit etwas Großes enden, egal was du tust; Sie müssen immer noch 1000 Elemente berücksichtigen.

6

Es gibt keine eingebaute Möglichkeit, ein Array zu erstellen und alle Elemente darin zu erstellen, so dass es nicht einmal annähernd so einfach ist, wie es sein soll. Es wird so viel Arbeit sein, wie es wirklich ist.

Sie ein Verfahren zum Erzeugen eines Arrays und alle Objekte in es machen kann:

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

Dann können Sie verwenden, eine dreistufige gezackten Array zu erstellen:

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

Nizza Verwendung von rekursiven generic def initions ... – thecoop

1

Es gibt keine " eleganter als das Schreiben der 2 For-Loops. Aus diesem Grund werden sie als "gezackt" bezeichnet, die Größe jedes Teilarrays kann variieren.

Aber das lässt die Frage: warum nicht die [,,] Version verwenden?

+3

Mehrdimensionale Arrays werden als ein großer Speicherblock zugewiesen, gezackte Arrays sind separate Blöcke. Wenn viel Speicher belegt ist, führt das mehrdimensionale Array eher zu OutOfMemoryException. Der Zugriff auf ein gezacktes Array ist auch schneller (da die CLR für SZ-Arrays optimiert ist - Single-Dimension, Null-basierte) – thecoop

+0

thecoop, Sie sind in beiden Punkten richtig, aber keiner ist so lang wie Größe = 10 oder sogar 100. Aber darüber hinaus summiert sich das schnell. –

+0

@thecoop, Haben Sie tatsächlich ** getestet ** was Sie behaupten? Ich bin neugierig. – strager

7

du versuchen könnte:

 

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

oder ohne explizite Werte:

 

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

Ich frage mich, warum das nicht gewählt ist ... für andere Typen als 'int':' double [] data = {new double [] {1, 4, 2}, new double [] {7, 4, 2, 1, 0.66, 5.44}, neues Doppel [] {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]));