I have code like this, which builds data to a specific format from an input collection, and appends a checksum value:
var data = input.Aggregate(new List<byte>(), (list, item) =>
{
list.Add(item.x);
list.Add(item.y);
list.Add(item.bytes.Length);
list.AddRange(item.bytes);
});
data.Add(Checksum(data));
var bytes = data.ToArray();
I interested to make this a single line but I cannot see how I can chain data
into Checksum()
which currently has the signature byte Checksum(IEnumerable<byte> input)
.
I thought I could do something like:
IEnumerable<byte> AddCheckSum(IList<byte> input)
{
return input.Add(Checksum(input));
}
var data = input.Aggregate(new List<byte>(), (list, item) =>
{
list.Add(item.x);
list.Add(item.y);
list.Add(item.bytes.Length);
list.AddRange(item.bytes);
}).AddChecksum().ToArray();
But I can't figure out how. Is it straighforward?
I doubt if you want Aggregate
at all; Linq seems to be more compact readable with SelectMany
and Concat
:
var data = input
.SelectMany(item => new byte[] {item.x, item.y, item.bytes.Length}.Concat(item.bytes));
var bytes = data
.Concat(new byte[] {Checksum(data)})
.ToArray();
but I suggest foreach
solution with explicit List<byte> data
:
List<byte> data = new List<byte>();
foreach (var item in input) {
data.Add(item.x);
data.Add(item.y);
data.Add(item.bytes.Length);
data.AddRange(item.bytes);
}
data.Add(Checksum(data));
var bytes = data.ToArray();
Finally, if you want to compute the fragment in one go, you can wrap it into an extension method :
public static class MyInputExtensions {
public static byte[] ToBytesWithCheckSum(this IEnumerable<MyInput> input) {
if (null == input)
throw new ArgumentNullException(nameof(input));
List<byte> data = new List<byte>();
foreach (var item in input) {
data.Add(item.x);
data.Add(item.y);
data.Add(item.bytes.Length);
data.AddRange(item.bytes);
}
data.Add(Checksum(data));
return data.ToArray();
}
}
then you can use ToBytesWithCheckSum()
as if it's a method of input
collection:
byte[] bytes = input.ToBytesWithCheckSum();
Use extension method.
public static class AddChecksumHelpers
{
public static IEnumerable<byte> AddCheckSum(this IEnumerable<byte> input)
{
return input.Concat(new[] { CheckSum(input) });
}
}
Or you could take and return List<byte>
if you have data in that format and directly return the input list (after calling .Add(CheckSum(input))
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.