C#での多次元配列・ジャグ配列の初期化 覚え書き


配列を同じ値で初期化

配列を初期化する場合、初期化子を使う。

// 10個の要素を0で初期化(newの場合は0で初期化される)
int[] table = new int[10];

// 5個の要素を1で初期化
int[] table2 = new int[]{1,1,1,1,1};

オーソドックスにforで回すんでもいいけどなんかカッコよくない。

int[] table = new int[5];
for(int i; i<table.Length; i++ ){
    table[i] = -1;
}

要素が少ない場合は初期化子でもいいんだけど、要素数が多いときはEnumerable.Repeatで
※ただし要素が参照型の場合は注意が必要(後述)

// 100個の要素を-1で初期化
int[] table = Enumerable.Repeat<int>(-1, 100).ToArray();

LINQのSelectを使う手もある。

// 100個の要素を-1で初期化
int[] table = (new int[100]).Select(v => -1).ToArray();

※ただし0で初期化するときはnewすればオッケー

// 100個の要素を0で初期化(intをnewした場合はゼロクリアされる)
int[] table = new int[100];

多次元配列でもいける

// 100x100x100の3次元配列を0で初期化
int[,,] table = new int[100,100,100];

ジャグ配列の0初期化

// 100x10のジャグ配列を0で初期化。forで回す。
int[][] table = new int[100][];
for(int i=0; i<table.Length; i++ ){
    table[i] = new int[10];
}

ジャグ配列を任意の値で初期化する場合。forで素直に書くとこう。

// 5x10のジャグ配列を-1で初期化
int[][] table = new int[5][];
for(int i=0; i<table.Length; i++ ){
    table[i] = new int[10];
    for (int j = 0; j < table[i].Length; j++) {
        table[i][j] = -1;
    }
}

ジャグ配列を同じ値で初期化する場合(その2)
Enumerable.Repeatを入れ子にすることでも可能。
※Enumerable.Repeatを使う場合、配列の型はint [,](多次元配列) ではなく int[][](ジャグ配列) になるので注意。

// 5x10のジャグ配列を-1で初期化
int[][] table = Enumerable.Repeat<int[]>((Enumerable.Repeat<int>(-1, 10).ToArray()), 5).ToArray();

// こっちはコンパイルエラー
// int[,] table = Enumerable.Repeat<int[]>((Enumerable.Repeat<int>(-1, 10).ToArray()), 5).ToArray();

※注意:多次元配列を以下のような書き方で生成してはいけません。
以下のようにRepeatを使って生成した場合、参照がコピーされてしまうため、table[0]〜table[4]に対して、new int[10]した配列がコピーされ、同じ場所をさしてしまいます。

参考:
https://qiita.com/nori0__/items/58d97201b479c3556e39#_reference-d439ef7d55bbcf2cd2a9
http://shirakamisauto.hatenablog.com/entry/2016/03/04/143710
http://emkcsharp.hatenablog.com/entry/2013/Advent

// こちらの書き方はNG。table[0][0]とtable[1][0] が同じ場所をさしてしまう
int[][] table = Enumerable.Repeat(new int[10], 5).ToArray();

ジャグ配列を同じ値で初期化する場合(その3)

Enumerable.RangeとLINQのSelectを組み合わせて使う方が見やすいかもしれません。
ToArrayが入れ子になるのが若干わかりにくいですが。。。

int[][] table = Enumerable.Range(0, 5).Select(y => (new int[10]).Select(x => -1).ToArray()).ToArray();

以上、覚え書きでした。

※多次元配列を任意の値で初期化する方法は不明。思いついたら書きます。

・参考:
[C#]配列の初期化いろいろ