c#将多个数组复制/合并到一个数组中的更好方法
Posted
技术标签:
【中文标题】c#将多个数组复制/合并到一个数组中的更好方法【英文标题】:c# A better way to Copy/Merge multiple arrays into one array 【发布时间】:2018-04-29 11:59:25 【问题描述】:谁能建议是否有更好的方法将多个数组复制到一个数组中?生成的数组必须具有相同顺序的元素,例如首先是 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]*/
【问题讨论】:
【参考方案1】:您可以只使用 LINQ .Concat
,这样您就不需要手动处理数组长度和偏移量:
var finalArray = arrayOne.Concat(arrayTwo).Concat(arrayThree).ToArray();
它的性能可能比使用Array.Copy
稍差,但这段代码更易读、更易维护且更安全,这一点更重要。
【讨论】:
谢谢!优雅的解决方案。我最终采用了这种方法。【参考方案2】:您可以将输入数组放在一个集合中并对其进行迭代。我只提到这一点是因为这可能比使用 LINQ 更有效。这取决于您正在处理的数据,但可能不足以产生影响。
在下面的代码中,在我的机器上,LINQ 需要 9000-13000 个滴答声(一个滴答声 = 100 ns),而调用 Array.Copy 大约是 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");
【讨论】:
谢谢。很棒的信息!当然,要考虑多次出现和更大的数组。在我的用例中,浪费的时间可以忽略不计,但请记住。【参考方案3】:通过预先创建一个大数组,然后使用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);
【讨论】:
很有趣,谢谢,BurnsBA 所关心的和 Yeldar Kurmangaliyev 的解决方案都是最好的。我会在某个阶段试一试。【参考方案4】:你必须使用数组吗?使用列表和 AddRange()。如果您最终需要一个数组,那么最后只需调用 ToArray()。
【讨论】:
谢谢,这实际上是一种可能性。更多的代码重构,但可能是值得的。【参考方案5】:var one = new [] arrayOne, arrayTwo, arrayThree .SelectMany(x => x);
【讨论】:
以上是关于c#将多个数组复制/合并到一个数组中的更好方法的主要内容,如果未能解决你的问题,请参考以下文章