listOfByteArrs.SelectMany(byteArr=>byteArr).ToArray()
Приведенный выше код конкатенации последовательности последовательности байтов в одну последовательность - и сохранить результат в виде массива.
Хотя читаемый, это не максимально эффективное - это не делает использование того факта, что вы уже знаете длину результирующего массива байт и, таким образом, можно избежать динамически расширенной .ToArray()
реализации, обязательно включает в себя несколько распределений и array- копии. Кроме того, SelectMany
реализован в терминах итераторов; это означает много + много вызовов интерфейса, которые довольно медленны. Тем не менее, для небольших размеров данных данных это вряд ли имеет значение.
Если вам нужна более быстрая реализация вы можете сделать следующее:
var output = new byte[listOfByteArrs.Sum(arr=>arr.Length)];
int writeIdx=0;
foreach(var byteArr in listOfByteArrs) {
byteArr.CopyTo(output, writeIdx);
writeIdx += byteArr.Length;
}
или Мартиньу предлагает:
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);
Некоторые тайминги:
var listOfByteArrs = Enumerable.Range(1,1000)
.Select(i=>Enumerable.Range(0,i).Select(x=>(byte)x).ToArray()).ToList();
Использование короткой метод для конкатенации этих 500500 байтов занимает 15 мс, используя fa st метод занимает 0,5 мс на моей машине - YMMV, и обратите внимание, что для многих приложений они более чем достаточно быстры ;-).
Наконец, вы можете заменить Array.CopyTo
с static
Array.Copy
, низким уровнем Buffer.BlockCopy
или MemoryStream
с предопределенным назад буфером - все они выполняют в значительной степени одинаково на моих тестах (x64 .NET 4.0).
Хотя короткий и понятный, обратите внимание, что этот код очень медленный по сравнению с традиционным решением. Если это достаточно быстро, здорово, но это может быть недостаточно быстро. –
Какое «традиционное решение»? – amalgamate
«Традиционное» решение, вероятно, было бы ручным, вложенным для циклов. Это примерно в три раза медленнее, чем решения на основе блок-копии, но все же в 10 раз быстрее, чем 'SelectMany'. –