2014年3月2日 星期日

[C#]將陣列切割成數個小陣列

最近又遇到一個奇妙的問題

就是對方提供的刪除資料的方法給我們

刪除小筆的資料(陣列)沒什麼問題

但是要刪除大筆資料的話就會出問題

在這種情況下最直觀的解決方法就是把原來的陣列切成數個小陣列

在一一丟進去給該方法刪除直到全部的內容刪除完畢

解法如下

int[] arr = new int[43];
Random rand=new Random(47);
for (int i = 0; i < arr.Length; i++)
{
    arr[i] = rand.Next()%100;
    Response.Write(arr[i]+" ");
}
Response.Write("<br>");

Array[] arr2 = null;

Response.Write("arr.Length=" + arr.Length + "<br>");

if (arr.Length % 20 == 0)
    arr2 = new Array[(arr.Length / 20)];
else
    arr2 = new Array[(arr.Length / 20) + 1];

for (int i = 0, index = 0; i < arr2.Length; i++)
{
    if (arr.Length - index >= 20)
    {
        arr2[i] = Array.CreateInstance(typeof(Int32), 20);
        Array.Copy(arr, index, arr2[i], 0, 20);
        index += 20;
    }
    else if (arr.Length - index > 0)
    {
        arr2[i] = Array.CreateInstance(typeof(Int32), arr.Length - index);
        Array.Copy(arr, index, arr2[i], 0, arr.Length - index);
    }
}
foreach (Array intArr in arr2)
{
    foreach (int delObj in intArr)
    {
        Response.Write(delObj+" ");
    }
    Response.Write("<br>");
}

程式在一開始亂數產生一個int陣列紀錄到arr陣列

arr2代表著新的陣列,使用Array類別當型別,代表著切割之後的每個reference指向一個一維陣列

每個新的陣列都有個長度(代表你每次傳進去刪除方法中的陣列有多長),這邊範例是20

當陣列在產生時會有兩種情況

第一你的陣列長度剛好可以被20整除,那表示你需要長度為n/20的陣列

第二你的陣列長度無法被20整除,那表示你需要長度為(n/20)+1的陣列

之後的迴圈代表將每筆資料copy至新陣列中

index代表目前指向舊陣列哪個索引

如果舊陣列長度減掉index大於等於20

那麼就用CreateInstance(typeof(Int32), 20)產生一個型態為Int32,長度為20的陣列(此時內容為空)給arr2[i]

之後用Array.Copy(arr, index, arr2[i], 0, 20);

複製arr陣列中從索引index開始到arr2[i] 中,長度為20的內容

完成後再將index加上20代表就陣列的索引往後移動20指到新的開頭

持續這個動作一直到arr.Length - index沒有大於等於20

則利用arr.Length - index判斷目前還剩下幾個元素未copy

測試範例如下


用這方法是真的有把問題解決了

但這其實不是最好的解法

其實我想的是能否直接將reference指到新的陣列而非用copy

畢竟用copy表示系統中會出現兩筆一模一樣的資料

copy的陣列越大消耗的系統資源也越大

也許是我對C#還不夠熟悉

如果有想到更好的解法再貼上來吧~

沒有留言:

張貼留言