DOBON.NET DOBON.NETプログラミング掲示板過去ログ

2次元配列のサイズ変更

環境/言語:[ASP.NET C#) .NET Framework1.1]
分類:[ASP.NET]

2次元配列のサイズ変更をここの「C#でReDim Preserveの代わりになるものは?」
というTip'sを参考にして作成したのですが、動かしてみますと、サイズは変更するが、値の格納場所(インデックス)がずれてしまう現象が出ました。
以下、方法でやっていますが何かまずいところがあるのでしょうか?
すみませんが、お知恵を貸してください。

for(Int32 i= 0;i <= ds.Tables[0].Rows.Count - 1;i++) {
int[,] newNumbers2 = new int[strWork1.Length,i+1];
Array.Copy(intLevCnt, newNumbers2, intLevCnt.Length);
intLevCnt = newNumbers2;

//配列にデータをセット
処理略
}

intLevCntに
[0,0]=0
[0,1]=1
だったものがサイズを変更した時点で(デバッグモードで確認)
[0,0]=1
[0,1]=0
[0,2]=0
となってしまいます。
多次元配列のときは、1次元目の要素ごとに
2次元目の要素をコピーしなければいけないのではないでしょうか?

//要素数2×5の配列を作る
int[][] intArray = new int[][]{new int[]{0, 1, 2, 3, 4}, new int[]{5, 6, 7, 8, 9}};
//要素数2×6の配列を作る
int[][] newArray = new int[2][];
newArray[0] = new int[6];
newArray[1] = new int[6];
//配列の要素をコピーする
Array.Copy(intArray[0], newArray[0], 
    Math.Min(intArray[0].Length, newArray[0].Length));
Array.Copy(intArray[1], newArray[1], 
    Math.Min(intArray[1].Length, newArray[1].Length));

//できた配列をintArrayに戻す
intArray = newArray;


C#でReDim Preserveの代わりになるものは?
http://dobon.net/vb/dotnet/vb2cs/redimpreserve.html
を参考にしました。
あれ…C#になってジャグ配列と二次元配列って分かれたんじゃなかったっけ…?

それは置いといて、int someary[,] は someary[行,列] であって、
変更しているのは行の方になるんとちゃう?
※全然見当違いのこと言っている希ガス…
Array.Copyのヘルプを読むと、

「多次元配列間でコピーする場合、概念的には、配列は各行 (または列) の先頭と末尾をつなげて並べた長い 1 次元配列のように動作します。」

とあるため、この方法では、一番初めの次元の要素数を増やした時だけうまくいくのではないでしょうか。(しかしこの場合でも、リュウさんが示されたように、[0,0]の値が変わることはありませんので、別の原因があるかもしれません。)

よって、それ以外の次元の要素数を変更する場合は、かなり面倒になりそうです。とりあえず、最後の次元の要素数を増やす場合のコードを書いてみました。適当なので、間違いがあるかもしれません。

int[,] oldArray = {{1,2},{3,4}};
int[,] newArray = new int[2,3];

int oldLastLenght = oldArray.GetLength(newArray.Rank - 1);
int newLastLength = newArray.GetLength(newArray.Rank - 1);
int oldStart = 0;
int newStart = 0;
for (int dm = 0; dm < oldArray.Rank - 1; dm++)
{
for (int i = 0; i < oldArray.GetLength(dm); i++)
{
Array.Copy(oldArray, oldStart,
newArray, newStart, oldLastLenght);
oldStart += oldLastLenght;
newStart += newLastLength;
}
}
皆さんご意見ありがとうございます。
以下の邪道なやり方でとりあえず解決しましたが処理のレスポンスが
悪そうなので、様子を見て、皆さんのやり方を利用させていただく
ことにします。
ほんとにありがとうございました。


//サイズを変更
newNumbers1 = new int[intPaipuCnt.GetLength(0),i+1];
newNumbers2 = new int[intPaipuCnt.GetLength(0),i+1];

for ( Int32 u=0; u<intPaipuCnt.GetLength(0); u++ ){
for ( Int32 t=0; t<intPaipuCnt.GetLength(1); t++ ){
newNumbers1[u,t] = intPaipuCnt[u,t];
newNumbers2[u,t] = intLevCnt[u,t];
}
}

intPaipuCnt = newNumbers1;
intLevCnt = newNumbers2;
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板