listOfByteArrs.SelectMany(byteArr=>byteArr).ToArray()
El código anterior concatenará una secuencia de secuencias de bytes en una secuencia y almacenará el resultado en una matriz. No se trata de hacer uso del hecho de que ya sabe la longitud de la matriz de bytes resultante y por lo tanto puede evitar la .ToArray()
aplicación extendida de forma dinámica que necesariamente implica múltiples asignaciones y Expandido -
Aunque legible, esto no es de máxima eficiencia copias. Además, el SelectMany
se implementa en términos de iteradores; esto significa mucho + muchas llamadas a la interfaz, lo que es bastante lento. Sin embargo, para tamaños pequeños de conjuntos de datos, es poco probable que esto importe.
Si necesita una aplicación más rápido se puede hacer lo siguiente:
var output = new byte[listOfByteArrs.Sum(arr=>arr.Length)];
int writeIdx=0;
foreach(var byteArr in listOfByteArrs) {
byteArr.CopyTo(output, writeIdx);
writeIdx += byteArr.Length;
}
o como Martinho sugiere:
var output = new byte[listOfByteArrs.Sum(arr => arr.Length)];
using(var stream = new MemoryStream(output))
foreach (var bytes in listOfByteArrs)
stream.Write(bytes, 0, bytes.Length);
Algunos tiempos:
var listOfByteArrs = Enumerable.Range(1,1000)
.Select(i=>Enumerable.Range(0,i).Select(x=>(byte)x).ToArray()).ToList();
Usando el corto método para concatenar estos 500500 bytes lleva 15 ms, utilizando el fa El método st toma 0.5ms en mi máquina - YMMV, y tenga en cuenta que para muchas aplicaciones ambas son más que suficientemente rápidas ;-).
Por último, podría reemplazar Array.CopyTo
con el static
Array.Copy
, el bajo nivel de Buffer.BlockCopy
, o una MemoryStream
con un búfer preasignado espalda - todos éstos realizan más o menos idéntica en mis pruebas (x64 .NET 4.0).
Aunque es corto y claro, tenga en cuenta que este código es muy lento en comparación con la solución tradicional. Si es lo suficientemente rápido, genial, pero puede que no sea lo suficientemente rápido. –
¿Cuál es la "solución tradicional"? – amalgamate
La solución "tradicional" probablemente sería manual, anidada para bucles. Eso es aproximadamente tres veces más lento que las soluciones basadas en bloques de copias, pero aún 10 veces más rápido que 'SelectMany'. –