我在c#中有3个字节数组,我需要合并成一个。完成这项任务最有效的方法是什么?
当前回答
我以Matt的LINQ为例,进一步提高了代码的洁净度:
byte[] rv = a1.Concat(a2).Concat(a3).ToArray();
在我的例子中,数组很小,所以我不关心性能。
其他回答
在我看来,许多答案都忽略了上述要求:
结果应该是一个字节数组 它应该尽可能地高效
这两者一起排除了字节的LINQ序列——任何带有yield的东西都不可能在不遍历整个序列的情况下获得最终大小。
当然,如果这些不是真正的需求,LINQ可能是一个完美的解决方案(或IList<T>实现)。然而,我假设超级哑铃知道他想要什么。
(编辑:我刚刚有了另一个想法。复制数组和惰性读取数组之间有很大的语义差异。考虑一下,如果在调用Combine(或其他方法)方法之后,但在使用结果之前更改其中一个“源”数组中的数据,会发生什么情况——使用惰性求值,该更改将是可见的。如果是即时拷贝,就不会了。不同的情况会要求不同的行为——这是需要注意的。)
以下是我建议的方法——当然,这些方法与其他一些答案中包含的方法非常相似:)
public static byte[] Combine(byte[] first, byte[] second)
{
byte[] ret = new byte[first.Length + second.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
return ret;
}
public static byte[] Combine(byte[] first, byte[] second, byte[] third)
{
byte[] ret = new byte[first.Length + second.Length + third.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
third.Length);
return ret;
}
public static byte[] Combine(params byte[][] arrays)
{
byte[] ret = new byte[arrays.Sum(x => x.Length)];
int offset = 0;
foreach (byte[] data in arrays)
{
Buffer.BlockCopy(data, 0, ret, offset, data.Length);
offset += data.Length;
}
return ret;
}
当然,“params”版本需要首先创建一个字节数组数组,这会带来额外的效率低下。
以下是@Jon Skeet提供的答案的概括。 它基本上是相同的,只是它可以用于任何类型的数组,而不仅仅是字节:
public static T[] Combine<T>(T[] first, T[] second)
{
T[] ret = new T[first.Length + second.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
return ret;
}
public static T[] Combine<T>(T[] first, T[] second, T[] third)
{
T[] ret = new T[first.Length + second.Length + third.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,
third.Length);
return ret;
}
public static T[] Combine<T>(params T[][] arrays)
{
T[] ret = new T[arrays.Sum(x => x.Length)];
int offset = 0;
foreach (T[] data in arrays)
{
Buffer.BlockCopy(data, 0, ret, offset, data.Length);
offset += data.Length;
}
return ret;
}
Concat是正确答案,但出于某种原因,手摇的东西得到了最多的选票。如果你喜欢这个答案,也许你会更喜欢这个通解:
IEnumerable<byte> Combine(params byte[][] arrays)
{
foreach (byte[] a in arrays)
foreach (byte b in a)
yield return b;
}
这可以让你做以下事情:
byte[] c = Combine(new byte[] { 0, 1, 2 }, new byte[] { 3, 4, 5 }).ToArray();
public static bool MyConcat<T>(ref T[] base_arr, ref T[] add_arr)
{
try
{
int base_size = base_arr.Length;
int size_T = System.Runtime.InteropServices.Marshal.SizeOf(base_arr[0]);
Array.Resize(ref base_arr, base_size + add_arr.Length);
Buffer.BlockCopy(add_arr, 0, base_arr, base_size * size_T, add_arr.Length * size_T);
}
catch (IndexOutOfRangeException ioor)
{
MessageBox.Show(ioor.Message);
return false;
}
return true;
}
memorystream类为我很好地完成了这项工作。我无法让缓冲类运行得像内存流一样快。
using (MemoryStream ms = new MemoryStream())
{
ms.Write(BitConverter.GetBytes(22),0,4);
ms.Write(BitConverter.GetBytes(44),0,4);
ms.ToArray();
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- 使用C返回一个数组
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 向对象数组添加属性
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>