我想用LINQ来解决以下问题,我有以下收藏:

List<byte> byteList = new List<byte() { 0x01, 0x00, 0x01, 0x02, 0x01, 0x00, 0x3, 0x4, 0x02 };

此示例中的数据遵循以下模式:

byteList[0] = 地址 (1, 2, 3, ... n)

byteList[1] = old state,基本代表一个枚举

byteList[2] = 新状态,同上

我正在与嵌入式设备交互,这就是我查看输入变化的方式。

为了清理代码并使维护程序员更容易遵循我的逻辑,我想抽象出一些涉及的细节,并将每个三字节的数据集提取到一个匿名类型中以供使用执行一些额外处理的函数。我已经编写了一个快速实现,但我相信它可以大大简化。我正在尝试清理代码,而不是让水变得浑浊!必须有一种更简单的方法来执行以下操作:
List<byte> byteList = new List<byte>()
{
    0x01, 0x09, 0x01, 0x02, 0x08, 0x02, 0x03, 0x07, 0x03
};
var addresses = byteList
    .Where((b, i) => i % 3 == 0)
    .ToList();
var oldValues = byteList
    .Where((b, i) => i % 3 == 1)
    .ToList();
var newValues = byteList
    .Where((b, i) => i % 3 == 2)
    .ToList();

var completeObjects = addresses
    .Select((address, index) => new
    {
        Address = address,
        OldValue = oldValues[index],
        NewValue = newValues[index]
    })
    .ToList();
foreach (var anonType in completeObjects)
{
    Console.WriteLine("Address: {0}\nOld Value: {1}\nNew Value: {2}\n",
        anonType.Address, anonType.OldValue, anonType.NewValue);
}

最佳答案

您可以使用 Enumerable.Range 和一点数学:

List<byte> byteList = new List<byte>()
{
    0x01, 0x09, 0x01, 0x02, 0x08, 0x02, 0x03, 0x07, 0x03
};
var completeObjects = Enumerable.Range(0, byteList.Count / 3).Select(index =>
    new
    {
        Address = byteList[index * 3],
        OldValue = byteList[index * 3 + 1],
        NewValue = byteList[index * 3 + 2],
    });

如果字节数不是 3 的倍数,多余的一两个字节将被忽略。

关于c# - 如何巧妙地从 IEnumerable<T> 创建匿名类型?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9813499/

10-09 00:25