繁体   English   中英

c# 一种将多个数组复制/合并到一个数组中的更好方法

[英]c# A better way to Copy/Merge multiple arrays into one array

任何人都可以建议是否有更好的方法将多个数组复制到单个数组中? 结果数组必须具有相同顺序的元素,例如首先是arrayOne值,然后是arraySecond值等。

以下是我目前正在执行的按预期工作的模型。 寻找一种更聪明的方法来做到这一点。

// Initialise the first array.
string[] arrayOne = new string[5];
arrayOne[0] = "arrayOneValue[0]";
arrayOne[1] = "arrayOneValue[1]";
arrayOne[2] = "arrayOneValue[2]";
arrayOne[3] = "arrayOneValue[3]";
arrayOne[4] = "arrayOneValue[4]";

// Initialise the second array.
string[] arrayTwo = new string[6];
arrayTwo[0] = "arrayTwoValue[0]";
arrayTwo[1] = "arrayTwoValue[1]";
arrayTwo[2] = "arrayTwoValue[2]";
arrayTwo[3] = "arrayTwoValue[3]";
arrayTwo[4] = "arrayTwoValue[4]";
arrayTwo[5] = "arrayTwoValue[5]";

// Initialise the third array.
string[] arrayThree = new string[3];
arrayThree[0] = "arrayThreeValue[0]";
arrayThree[1] = "arrayThreeValue[1]";
arrayThree[2] = "arrayThreeValue[2]";

// string[] arrayN = new string[n]
//.
//.
//.

// Initialise the target array.
string[] finalArray = new string[arrayOne.Length + arrayTwo.Length + arrayThree.Length];
// ArrayN - string[] finalArray = new string[arrayOne.Length + arrayTwo.Length + arrayThree.Length + arrayN.Length];

// Copy/merge the three arrays into the target array.
Array.Copy(arrayOne, 0, finalArray, 0, arrayOne.Length);
Array.Copy(arrayTwo, 0, finalArray, arrayOne.Length, arrayTwo.Length);
Array.Copy(arrayThree, 0, finalArray, (arrayOne.Length + arrayTwo.Length), arrayThree.Length);
//.
//.
//.
//.
// ArrayN - Array.Copy(arrayN, 0, finalArray, (arrayOne.Length + arrayTwo.Length + arrayN), arrayN.Length) ?;

正如您所看到的,arrayN 的代码会变得更长。 我尝试将最多 5 个数组复制到一个数组中,因此,它是可管理的。 我将此技术用作 WebAPI 的一部分,其中一组 oracle 参数对象根据要传递给多个 Oracle 存储过程的业务规则进行整合。 任何建议在这里表示赞赏。 提前致谢。 结果

Console output 
/*--- Destination array -
arrayOneValue[0]
arrayOneValue[1]
arrayOneValue[2]
arrayOneValue[3]
arrayOneValue[4]
arrayTwoValue[0]
arrayTwoValue[1]
arrayTwoValue[2]
arrayTwoValue[3]
arrayTwoValue[4]
arrayTwoValue[5]
arrayThreeValue[0]
arrayThreeValue[1]
arrayThreeValue[2]*/

您可以只使用LINQ .Concat ,这样就无需手动处理数组的长度和偏移量:

var finalArray = arrayOne.Concat(arrayTwo).Concat(arrayThree).ToArray();

它的性能可能不如使用Array.Copy ,但是此代码更具可读性,可维护性和错误安全性,这一点更为重要。

您可以将输入数组放入集合中并对其进行迭代。 我仅提及这一点,因为这可能比使用LINQ更有效。 这取决于您要处理的数据,但可能不足以发挥作用。

在下面的代码中,在我的机器上,LINQ在调用Array时花费了9000-13000个滴答声(1个滴答声= 100 ns),复制约为500个滴答声。

public static void Benchmark1()
{
    var arr1 = Enumerable.Range(1,10000).ToArray();
    var arr2 = Enumerable.Range(10001,20000).ToArray();
    var arr3 = Enumerable.Range(20001,30000).ToArray();
    var arr4 = Enumerable.Range(30001,40000).ToArray();

    var sw = Stopwatch.StartNew();
    var result = arr1.Concat(arr2).Concat(arr3).Concat(arr4).ToArray();
    sw.Stop();
    Console.WriteLine($"Elpased ticks: {sw.ElapsedTicks}");
}

public static void Benchmark2()
{
    var arr1 = Enumerable.Range(1,10000).ToArray();
    var arr2 = Enumerable.Range(10001,20000).ToArray();
    var arr3 = Enumerable.Range(20001,30000).ToArray();
    var arr4 = Enumerable.Range(30001,40000).ToArray();

    var arrays = new List<int[]>() {arr1, arr2, arr3, arr4};

    var sw = Stopwatch.StartNew();

    int finalLen = 0;
    foreach (var arr in arrays)
    {
        finalLen += arr.Length;
    }

    var result = new int[finalLen];
    int currentPosition = 0;

    foreach (var arr in arrays)
    {
        Array.Copy(arr, 0, result, currentPosition, arr.Length);
        currentPosition += arr.Length;
    }

    sw.Stop();
    Console.WriteLine($"Elpased ticks: {sw.ElapsedTicks}");
}

通过在前面创建一个大数组,然后使用Array.Copy ,即使有大量数组,我们也可以实现非常合理的连接速度:

public static T[] ConcatArrays<T>(params T[][] p)
{
    var position = 0;
    var outputArray = new T[p.Sum(a => a.Length)];
    foreach (var curr in p)
    {
        Array.Copy(curr, 0, outputArray, position, curr.Length);
        position += curr.Length;
    }
    return outputArray;
}

因此,现在我们可以:

string bigArray = ConcatArrays(arrayOne, arrayTwo, arrayThree)

要么

string[][] arrays = new[]{arrayOne, arrayTwo, arrayThree};
string bigArray = ConcatArrays(arrays);

您必须使用数组吗? 使用列表和AddRange()。 如果最终需要一个数组,则只需最后调用ToArray()。

var one =  new [] { arrayOne, arrayTwo, arrayThree }.SelectMany(x => x);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM