在.NET中合并两个数组

有没有在.NET 2.0中的内置函数,将采取两个数组,并将它们合并成一个数组?

数组都是相同的types。 我从我的代码库中广泛使用的函数中获取这些数组,并且不能修改函数以不同的格式返回数据。

我正在寻求避免写我自己的function,如果可能的话就做到这一点。

如果您可以操作其中一个数组,则可以在执行复制之前调整它的大小:

T[] array1 = getOneArray(); T[] array2 = getAnotherArray(); int array1OriginalLength = array1.Length; Array.Resize<T>(ref array1, array1OriginalLength + array2.Length); Array.Copy(array2, 0, array1, array1OriginalLength, array2.Length); 

否则,你可以创build一个新的数组

 T[] array1 = getOneArray(); T[] array2 = getAnotherArray(); T[] newArray = new T[array1.Length + array2.Length]; Array.Copy(array1, newArray, array1.Length); Array.Copy(array2, 0, newArray, array1.Length, array2.Length); 

更多关于MSDN上可用的数组方法 。

在C#3.0中,您可以使用LINQ的Concat方法轻松完成此操作:

 int[] front = { 1, 2, 3, 4 }; int[] back = { 5, 6, 7, 8 }; int[] combined = front.Concat(back).ToArray(); 

在C#2.0中,你没有这种直接的方式,但Array.Copy可能是最好的解决scheme:

 int[] front = { 1, 2, 3, 4 }; int[] back = { 5, 6, 7, 8 }; int[] combined = new int[front.Length + back.Length]; Array.Copy(front, combined, front.Length); Array.Copy(back, 0, combined, front.Length, back.Length); 

这可以很容易地用来实现你自己的Concat版本。

使用LINQ :

 var arr1 = new[] { 1, 2, 3, 4, 5 }; var arr2 = new[] { 6, 7, 8, 9, 0 }; var arr = arr1.Union(arr2).ToArray(); 

首先,确保你问自己这个问题:“我真的应该在这里使用数组吗?

除非你正在构build速度至关重要的东西,否则一个types化的List,比如List<int>可能是要走的路。 我唯一一次使用数组是通过networking发送东西时的字节数组。 除此之外,我从不碰他们。

更简单的就是使用LINQ :

 var array = new string[] { "test" }.ToList(); var array1 = new string[] { "test" }.ToList(); array.AddRange(array1); var result = array.ToArray(); 

首先将数组转换为列表并合并它们…之后,只需将列表转换回数组:)

我想你可以使用Array.Copy 。 它需要一个源索引和目标索引,所以你应该能够将一个数组附加到另​​一个。 如果你需要变得更复杂,而不仅仅是将一个追加到另一个,这可能不适合你。

就我个人而言,我更喜欢我自己的语言扩展,我随意添加或删除了快速原型。

以下是string的示例。

 //resides in IEnumerableStringExtensions.cs public static class IEnumerableStringExtensions { public static IEnumerable<string> Append(this string[] arrayInitial, string[] arrayToAppend) { string[] ret = new string[arrayInitial.Length + arrayToAppend.Length]; arrayInitial.CopyTo(ret, 0); arrayToAppend.CopyTo(ret, arrayInitial.Length); return ret; } } 

它比LINQ和Concat快得多。 更快的是,正在使用一个自定义的IEnumerabletypes包装,它存储了传递数组的引用/指针,并允许在整个集合上循环,就像它是一个正常的数组。 (在HPC,graphics处理,graphics渲染中有用…)

你的代码:

 var someStringArray = new[]{"a", "b", "c"}; var someStringArray2 = new[]{"d", "e", "f"}; someStringArray.Append(someStringArray2 ); //contains a,b,c,d,e,f 

整个代码和generics版本请参阅: https : //gist.github.com/lsauer/7919764

注意:这将返回一个未扩展的IEnumerable对象。 返回一个扩展对象有点慢。

自2002年以来,我编译了这样的扩展,有很多学分会转给CodeProject和“Stackoverflow”上的帮助人员。 我会很快发布,并把链接放在这里。

每个人都已经有了发言权,但我认为这比“用作扩展方法”的方法更可读:

 var arr1 = new[] { 1, 2, 3, 4, 5 }; var arr2 = new[] { 6, 7, 8, 9, 0 }; var arr = Queryable.Concat(arr1, arr2).ToArray(); 

但是它只能在将两个数组放在一起时使用。

假设目标数组有足够的空间, Array.Copy()将工作。 您也可以尝试使用List <T>及其.AddRange()方法。

如果你不想删除重复,那么试试这个

使用LINQ:

 var arr1 = new[] { 1, 2, 3, 4, 5 }; var arr2 = new[] { 6, 7, 8, 9, 0 }; var arr = arr1.Concat(arr2).ToArray(); 

如果有人正在寻找如何合并两个图像字节数组:

  private void LoadImage() { string src = string.empty; byte[] mergedImageData = new byte[0]; mergedImageData = MergeTwoImageByteArrays(watermarkByteArray, backgroundImageByteArray); src = "data:image/png;base64," + Convert.ToBase64String(mergedImageData); MyImage.ImageUrl = src; } private byte[] MergeTwoImageByteArrays(byte[] imageBytes, byte[] imageBaseBytes) { byte[] mergedImageData = new byte[0]; using (var msBase = new MemoryStream(imageBaseBytes)) { System.Drawing.Image imgBase = System.Drawing.Image.FromStream(msBase); Graphics gBase = Graphics.FromImage(imgBase); using (var msInfo = new MemoryStream(imageBytes)) { System.Drawing.Image imgInfo = System.Drawing.Image.FromStream(msInfo); Graphics gInfo = Graphics.FromImage(imgInfo); gBase.DrawImage(imgInfo, new Point(0, 0)); //imgBase.Save(Server.MapPath("_____testImg.png"), ImageFormat.Png); MemoryStream mergedImageStream = new MemoryStream(); imgBase.Save(mergedImageStream, ImageFormat.Png); mergedImageData = mergedImageStream.ToArray(); mergedImageStream.Close(); } } return mergedImageData; } 

这是一个使用Array.CopyTo的简单例子。 我认为它回答你的问题,并给出了一个CopyTo使用的例子 – 当我需要使用这个函数时,我总是感到困惑,因为帮助有点不清楚 – 索引是发生插入的目标数组中的位置。

 int[] xSrc1 = new int[3] { 0, 1, 2 }; int[] xSrc2 = new int[5] { 3, 4, 5, 6 , 7 }; int[] xAll = new int[xSrc1.Length + xSrc2.Length]; xSrc1.CopyTo(xAll, 0); xSrc2.CopyTo(xAll, xSrc1.Length); 

我想你不能简单得多。

只是要注意一个选项:如果你正在使用的数组是基本types – 布尔(bool),Char,SByte,Byte,Int16(short),UInt16,Int32(int),UInt32,Int64(long ),UInt64,IntPtr,UIntPtr,单或双 – 那么你可以(或应该?)尝试使用Buffer.BlockCopy 。 根据缓冲类的MSDN页面:

这个类比System.Array类中的类似方法提供了更好的操作基本types的性能。

以@ OwenP的答案中的C#2.0为例,它的工作原理如下:

 int[] front = { 1, 2, 3, 4 }; int[] back = { 5, 6, 7, 8 }; int[] combined = new int[front.Length + back.Length]; Buffer.BlockCopy(front, 0, combined, 0, front.Length); Buffer.BlockCopy(back, 0, combined, front.Length, back.Length); 

Buffer.BlockCopy和@OwenP使用的Array.Copy在语法上几乎没有什么区别,但是这应该会更快(即使只是略微)。

我假设你正在使用自己的数组types,而不是内置的.NET数组:

 public string[] merge(input1, input2) { string[] output = new string[input1.length + input2.length]; for(int i = 0; i < output.length; i++) { if (i >= input1.length) output[i] = input2[i-input1.length]; else output[i] = input1[i]; } return output; } 

另一种方法是使用内build的ArrayList类。

 public ArrayList merge(input1, input2) { Arraylist output = new ArrayList(); foreach(string val in input1) output.add(val); foreach(string val in input2) output.add(val); return output; } 

这两个例子都是C#。

 int [] SouceArray1 = new int[] {2,1,3}; int [] SourceArray2 = new int[] {4,5,6}; int [] targetArray = new int [SouceArray1.Length + SourceArray2.Length]; SouceArray1.CopyTo(targetArray,0); SourceArray2.CopyTo(targetArray,SouceArray1.Length) ; foreach (int i in targetArray) Console.WriteLine(i + " "); 

使用上面的代码,两个数组可以很容易地合并。

此代码适用于所有情况:

 int[] a1 ={3,4,5,6}; int[] a2 = {4,7,9}; int i = a1.Length-1; int j = a2.Length-1; int resultIndex= i+j+1; Array.Resize(ref a2, a1.Length +a2.Length); while(resultIndex >=0) { if(i != 0 && j !=0) { if(a1[i] > a2[j]) { a2[resultIndex--] = a[i--]; } else { a2[resultIndex--] = a[j--]; } } else if(i>=0 && j<=0) { a2[resultIndex--] = a[i--]; } else if(j>=0 && i <=0) { a2[resultIndex--] = a[j--]; } } 

创build和扩展方法来处理null

 public static class IEnumerableExtenions { public static IEnumerable<T> UnionIfNotNull<T>(this IEnumerable<T> list1, IEnumerable<T> list2) { if (list1 != null && list2 != null) return list1.Union(list2); else if (list1 != null) return list1; else if (list2 != null) return list2; else return null; } } 

尝试这个:

 ArrayLIst al = new ArrayList(); al.AddRange(array_1); al.AddRange(array_2); al.AddRange(array_3); array_4 = al.ToArray();