.NET 2.0中是否有一个内置函数,可以将两个数组合并成一个数组?

这两个数组具有相同的类型。我从代码库中广泛使用的函数中获得这些数组,并且不能修改该函数以以不同的格式返回数据。

如果可能的话,我希望避免编写自己的函数来完成这个任务。


当前回答

我想找到一种不使用数组本身以外的任何库或功能的方法。

前两个示例主要用于从头读取逻辑,但我也想知道是否会根据情况而有性能变化。

第三个例子是最实际的选择。

// Two for-loops
private static int[] MergedArrays_1(int[] a, int[] b)
{
    int[] result = new int[a.Length + b.Length];
    for (int i = 0; i < a.Length; i++)
    {
        result[i] = a[i];
    }
    for (int i = a.Length; i < result.Length; i++)
    {
        result[i] = b[i - a.Length];
    }
    return result;
}

// One for-loop
private static int[] MergedArrays_2(int[] a, int[] b)
{
    int[] results = new int[a.Length + b.Length];
    for (int i = 0; i < results.Length; i++)
    {
        results[i] = (i < a.Length) ? a[i] : b[i - a.Length];
    }
    return results;
}

// Array Method
private static int[] MergedArrays_3(int[] a, int[] b)
{
    int[] results = new int[a.Length + b.Length];
    a.CopyTo(results, 0);
    b.CopyTo(results, a.Length);
    return results;
}

最后,我做了第四个例子,可以合并多个数组,使用params关键字。

int[] result = MultipleMergedArrays(arrayOne, arrayTwo, arrayThree);
private static int[] MultipleMergedArrays(params int[][] a)
{
    // Get Length
    int resultsLength = 0;
    for (int row = 0; row < a.GetLength(0); row++)
    {
        resultsLength += a.Length;
    }

    // Initialize
    int[] results = new int[resultsLength];

    // Add Items
    int index = 0;
    for (int row = 0; row < a.GetLength(0); row++)
    {
        a[row].CopyTo(results, index);
        index += a[row].Length;
    }
    return results;
}

当使用参数时,它的工作方式是将一维数组传递到锯齿数组中。

GetLength(0)返回锯齿状数组中包含的数组数。

该代码首先计算所有数组的Length,然后根据该大小初始化一个新数组,并开始使用CopyTo()方法将整个数组添加到新的结果数组中,同时将每个添加的数组的Length添加到索引计数器中。

PS:在合并时,有时需要从数组中删除空项或某些项。

private static int[] RemoveEmpty(int[] array)
{
    int count = 0;
    for (int i = 0; i < array.Length; i++)
    {
        if (array[i] == 0) count++;
    }

    int[] result = new int[array.Length - count];

    count = 0;
    for (int i = 0; i < array.Length; i++)
    {
        if (array[i] == 0) continue;
        result[count] = array[i];
        count++;
    }

    return result;
}

这个函数可以与上面的函数结合使用。

它接受一个数组,计算匹配为0的项的数量。并创建一个大小合适的新数组。然后计数器被回收并用作索引,用于将输入数组的值放入新的更小的结果数组中。 当一个项匹配0时,它将跳过该循环中的其余代码,并继续下一轮循环,不增加整数计数器。

其他回答

我想找到一种不使用数组本身以外的任何库或功能的方法。

前两个示例主要用于从头读取逻辑,但我也想知道是否会根据情况而有性能变化。

第三个例子是最实际的选择。

// Two for-loops
private static int[] MergedArrays_1(int[] a, int[] b)
{
    int[] result = new int[a.Length + b.Length];
    for (int i = 0; i < a.Length; i++)
    {
        result[i] = a[i];
    }
    for (int i = a.Length; i < result.Length; i++)
    {
        result[i] = b[i - a.Length];
    }
    return result;
}

// One for-loop
private static int[] MergedArrays_2(int[] a, int[] b)
{
    int[] results = new int[a.Length + b.Length];
    for (int i = 0; i < results.Length; i++)
    {
        results[i] = (i < a.Length) ? a[i] : b[i - a.Length];
    }
    return results;
}

// Array Method
private static int[] MergedArrays_3(int[] a, int[] b)
{
    int[] results = new int[a.Length + b.Length];
    a.CopyTo(results, 0);
    b.CopyTo(results, a.Length);
    return results;
}

最后,我做了第四个例子,可以合并多个数组,使用params关键字。

int[] result = MultipleMergedArrays(arrayOne, arrayTwo, arrayThree);
private static int[] MultipleMergedArrays(params int[][] a)
{
    // Get Length
    int resultsLength = 0;
    for (int row = 0; row < a.GetLength(0); row++)
    {
        resultsLength += a.Length;
    }

    // Initialize
    int[] results = new int[resultsLength];

    // Add Items
    int index = 0;
    for (int row = 0; row < a.GetLength(0); row++)
    {
        a[row].CopyTo(results, index);
        index += a[row].Length;
    }
    return results;
}

当使用参数时,它的工作方式是将一维数组传递到锯齿数组中。

GetLength(0)返回锯齿状数组中包含的数组数。

该代码首先计算所有数组的Length,然后根据该大小初始化一个新数组,并开始使用CopyTo()方法将整个数组添加到新的结果数组中,同时将每个添加的数组的Length添加到索引计数器中。

PS:在合并时,有时需要从数组中删除空项或某些项。

private static int[] RemoveEmpty(int[] array)
{
    int count = 0;
    for (int i = 0; i < array.Length; i++)
    {
        if (array[i] == 0) count++;
    }

    int[] result = new int[array.Length - count];

    count = 0;
    for (int i = 0; i < array.Length; i++)
    {
        if (array[i] == 0) continue;
        result[count] = array[i];
        count++;
    }

    return result;
}

这个函数可以与上面的函数结合使用。

它接受一个数组,计算匹配为0的项的数量。并创建一个大小合适的新数组。然后计数器被回收并用作索引,用于将输入数组的值放入新的更小的结果数组中。 当一个项匹配0时,它将跳过该循环中的其余代码,并继续下一轮循环,不增加整数计数器。

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 + " ");  

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

这是我想到的。适用于可变数量的数组。

public static T[] ConcatArrays<T>(params T[][] args)
    {
        if (args == null)
            throw new ArgumentNullException();

        var offset = 0;
        var newLength = args.Sum(arr => arr.Length); 
        var newArray = new T[newLength];

        foreach (var arr in args)
        {
            Buffer.BlockCopy(arr, 0, newArray, offset, arr.Length);
            offset += arr.Length;
        }

        return newArray;
    }

...

var header = new byte[] { 0, 1, 2};
var data = new byte[] { 3, 4, 5, 6 };
var checksum = new byte[] {7, 0};
var newArray = ConcatArrays(header, data, checksum);
//output byte[9] { 0, 1, 2, 3, 4, 5, 6, 7, 0 }

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

下面是一个字符串的例子。

//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快得多。更快的方法是使用一个自定义的IEnumerable类型包装器,它存储传递数组的引用/指针,并允许对整个集合进行循环,就像它是一个普通数组一样。(适用于高性能计算,图形处理,图形渲染…)

你的代码:

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

完整的代码和泛型版本请参见:https://gist.github.com/lsauer/7919764

注意:返回一个未扩展的IEnumerable对象。返回一个扩展对象稍微慢一些。

我从2002年开始编译这样的扩展,有很多功劳要归功于CodeProject和“Stackoverflow”上的乐于助人的人。我很快就会发布这些,并把链接放在这里。

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

使用LINQ:

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