2013-07-06 41 views
5

我想問如何切片數組而不使用Array.Copy。 我會給你一個我想要達到的例子,以便你能理解我。正確的窗體切片C#中的數組#

比方說,我有這個數組。稱爲原始

[1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15]

我想從給定的某些長度的起始索引的副本陣列,可以說,我想元件之一元件6我想要的代碼,以執行該任務如

int startIndex = 0; 
int lenght= 5; 
int[] CopyArray = ArrayFromRange(Original, startIndex, length); 

然後copyArray將be:

[1 | 2 | 3 | 4 | 5] 我不希望使用Array.Copy,因爲我會循環這讓隨後的片

,所以我會做

int length = 3; 
for(int i = 0; i < OriginalArray.Length; i++) 
{ 
    int[] CopyArray = ArrayFromRange(OriginalArray, i, length); 
    // perform some operations 
} 

這會給我每次4個元素循環執行的數組它然後我會做一些操作。但是如果我做了Array.Copy它會拋出一個OutOfBoundsException當我在循環中獲得值13時,它會嘗試複製不存在的數組[15]。我想避免這些錯誤。

我上的WinForms開發,.NET 4.0

+0

不像論壇網站,我們不使用「謝謝」或「任何幫助表示讚賞」,或在[so]上簽名。請參閱「[應該'嗨','謝謝',標語和致敬從帖子中刪除?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be -removed-from-posts) –

回答

8

我認爲,對待你的方式將符合IEnumerable的對象,特別是使用LINQ的最佳途徑。 IEnumerable是一個接口,意思是「你可以調用這個對象的foreach」。它是爲數組實現的,也是用於查詢集合的其他對象的一部分 - 您不需要特別知道這些對象是什麼;只需在需要時列舉每件物品。

using System.Linq; // put this at the top of the .cs, not mid-code. 

int startIndex = 0; 
int lenght= 5; 
IEnumerable<int> CopyArray = Original.Skip(startIndex).Take(lenght); 

我在記事本中寫道,所以有可能是我錯過了一些小事情,但那應該會給你你需要的東西。你可以跳過.Skip(的startIndex)的一部分,如果它總是會爲0訪問每個INT:

foreach (int value in CopyArray) { 
    // TODO with value?? 
} 
+1

請注意,您可能希望在該結尾處添加一個額外的'.ToArray()'或'.ToList()',否則其執行將延遲並在每次迭代時運行。這意味着如果原始數組中的值發生變化,則'CopyArray'將在迭代時產生更改的值。編輯:您可能還想提及'Skip'和'Take'足夠寬大以至於不會拋出'IndexOutOfRangeException'錯誤。 –

+0

啊,是的,絕對。這對於所有的用例來說都不是最佳的,但它聽起來像是針對手頭的問題。另一方面,有一些有趣的情況是有一個變量可以自動執行過濾/排序/等。 – Katana314

+0

@Chris辛克萊謝謝你,這是我需要的。 我幾乎不知道有關Linq的任何內容,但在閱讀Skip,Take和ToArray()的文檔後,我能夠對其進行編碼,並且更重要,理解它。 – HardCodeStuds

0

你仍然可以使用Array.Copy(),但你只需要確保該指數在範圍內:

T[] ArrayFromRange<T>(T[] originalArray, int startIndex, int length) 
{ 
    int actualLength = Math.Min(length, originalArray.Length - startIndex); 
    T[] copy = new T[actualLength]; 
    Array.Copy(originalArray, startIndex, copy, 0, actualLength); 
    return copy; 
} 

在你的例子中,循環中的最後兩個數組是{14,15}{15}

0

如果你喜歡它返回一個縮短的陣列的方法,我可以提供其中的一個,但我假定這是你想要什麼:(是的,這已經過測試)

using System; 
namespace ArraySlice 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      byte[] array1 = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 }; 
      byte[] array2 = GetSlice<byte>(array1, 5, 10); 
      for (int i = 0; i < array2.Length; i++) 
      { 
       Console.WriteLine(array2[i]); 
      } 
      Console.ReadKey(); 
     } 
     static T[] GetSlice<T>(T[] array, int start, int length) 
     { 
      T[] result = new T[length]; 
      for (int i = 0; i < length; i++) 
      { 
       result[i] = ((start + i) < array.Length) ? array[start + i] : default(T); 
      } 
      return result; 
     } 
    } 
}