listOfByteArrs.SelectMany(byteArr=>byteArr).ToArray()
Mã trên sẽ nối chuỗi trình tự byte thành một chuỗi - và lưu kết quả vào một mảng.
Mặc dù có thể đọc được, đây không phải là tối đa hiệu quả - nó không làm cho việc sử dụng thực tế là bạn đã biết chiều dài của mảng byte kết quả và do đó có thể tránh được tự động mở rộng .ToArray()
thực hiện điều đó nhất thiết liên quan đến nhiều phân bổ và array- bản sao. Hơn nữa, SelectMany
được thực hiện theo vòng lặp; điều này có nghĩa là rất nhiều + rất nhiều cuộc gọi giao diện khá chậm. Tuy nhiên, đối với các kích thước tập dữ liệu nhỏ-ish thì điều này không quan trọng.
Nếu bạn cần triển khai nhanh hơn bạn có thể làm như sau:
var output = new byte[listOfByteArrs.Sum(arr=>arr.Length)];
int writeIdx=0;
foreach(var byteArr in listOfByteArrs) {
byteArr.CopyTo(output, writeIdx);
writeIdx += byteArr.Length;
}
hoặc như Martinho gợi ý:
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);
Một số timings:
var listOfByteArrs = Enumerable.Range(1,1000)
.Select(i=>Enumerable.Range(0,i).Select(x=>(byte)x).ToArray()).ToList();
Sử dụng ngắn phương pháp để ghép các 500500 byte này mất 15ms, sử dụng fa phương pháp st mất 0,5ms trên máy tính của tôi - YMMV, và lưu ý rằng đối với nhiều ứng dụng cả hai đều nhanh hơn đủ ;-).
Cuối cùng, bạn có thể thay thế Array.CopyTo
với static
Array.Copy
, cấp thấp Buffer.BlockCopy
, hoặc một MemoryStream
với một bộ đệm preallocated trở lại - đây là tất cả thực hiện khá nhiều hệt các bài kiểm tra của tôi (x64 .NET 4.0).
Nguồn
2011-02-02 15:05:44
Mặc dù ngắn gọn và rõ ràng, lưu ý rằng mã này rất chậm so với giải pháp truyền thống. Nếu nó đủ nhanh, tuyệt vời, nhưng nó có thể không đủ nhanh. –
Đó là "giải pháp truyền thống"? – amalgamate
Giải pháp "truyền thống" có thể là thủ công, được lồng ghép cho các vòng lặp. Đó là khoảng ba lần chậm hơn so với các giải pháp dựa trên khối bản sao, nhưng vẫn nhanh hơn 10 lần so với 'SelectMany'. –