2010-12-09 81 views
0

比方說,我有一個名爲long[]IDs陣列中的幾個要素。C#:拼接陣列

什麼是定索引處拼接成/插入一個新元素的最簡單的方法?

現在我這樣做,我不認爲這是最佳的:

long[] IDs = ...; 

var IDsList = IDs.ToList(); 
IDsList.Insert(newId, indexToInsertAt); 

IDs = IDsList.ToArray(); 

沒有什麼內置到Array類?這讓我覺得非常奇怪,來自[].splice()的JavaScript世界。

+6

任何理由你正在使用一個列表? – 2010-12-09 20:36:04

+0

它讓我覺得奇怪的是來自PHP,但你有什麼是我在C#中使用的東西# – Dinah 2010-12-09 20:36:40

+1

沒有什麼內置到Array類,因爲這是什麼列表類是 – 2010-12-09 20:37:04

回答

11

使用List<long>而非陣列,因爲你需要做的插入。

6

這似乎有點奇怪,但很有可能被排除在外,以防止開發人員很容易寫性能差的代碼。 (如果要插入中間一個新的項目,你可能想要一個可調整大小的集合像List<T>)到「插入」到一個固定大小的採集像Array的唯一方法是將收集的內容複製到收集,並把項目那裏。顯然,如果您執行大量插入操作,這不是最好的辦法。

如果使用T[]陣列的是你的控制之外,並且插入是必要的,複製自己的數組至少是最好你有,因爲它可以節省你昂貴操作的代碼:複製和插入這要求可能有很多元素被一個索引「轉移」。 (您當前的解決方案複製long[]的內容轉換成一個List<long>,然後插入一個項目成List<long>然後將複製List<long>到一個新的long[]。)

在這種情況下(一個T[]的選擇是不可協商的),你可以考慮使用擴展方法來完成我剛剛描述的內容。這樣,至少你有一個場景,當你做需要此行爲的可重用的代碼。喜歡的東西:

public static class ArrayHelper 
{ 
    public static T[] Insert<T>(this T[] source, int index, T item) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException("source"); 
     } 

     if (index < 0 || index > source.Length) 
     { 
      throw new ArgumentOutOfRangeException("index"); 
     } 

     // Allocate a new array with enough space for one more item. 
     T[] result = new T[source.Length + 1]; 

     // Copy all elements before the insertion point. 
     for (int i = 0; i < index; ++i) 
     { 
      result[i] = source[i]; 
     } 

     // Insert the new value. 
     result[index] = item; 

     // Copy all elements after the insertion point. 
     for (int i = index; i < source.Length; ++i) 
     { 
      result[i + 1] = source[i]; 
     } 

     return result; 
    } 
} 

注意,上面是比你現在是怎樣,因爲它僅需要執行全陣列複製一個時間(不是兩次),相當於有效的多,也沒有按不需要元素的任何中間「移位」。

用法:

int[] numbers = new int[] { 2, 3, 4 }; 
numbers = numbers.Insert(0, 1); 

foreach (int number in numbers) 
{ 
    Console.WriteLine(number); 
} 

輸出:

 
1 
2 
3 
4 
1

有做類似的事情,這裏是我想出的,類似於丹道的:

T[] newArr = new T[oldArr.Length+1]; 

//copy first part of the array, starting with newArr[0] <- oldArr[0], up to the insertion point 
System.Array.Copy(oldArr, 0, newArr, 0, insertIndex, insertIndex); 

//insert new element 
newArr[insertIndex] = spliceElem; 

//copy the rest of the array, from newArr[insert+1] <- oldArr[insert] to the end 
System.Array.Copy(oldArr, insertIndex, newArr, insertIndex + 1, oldArr.Length-insertIndex); 
return newArr;