Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#如何将结构的数组转换为数组的结构_C#_Arrays_Data Structures_Struct - Fatal编程技术网

c#如何将结构的数组转换为数组的结构

c#如何将结构的数组转换为数组的结构,c#,arrays,data-structures,struct,C#,Arrays,Data Structures,Struct,我从一个IntPtr开始,它从发送周期性数据包的硬件源发送结构化数据。线程从Intptr缓冲区复制数据包,并将字节[]放入队列。稍后读取队列,字节[]转换为使用的结构,并成为数据包类型的集合(数组) struct Packet { long time; int field1; short field2; } Packet[] array_of_packet; 在不重复结构定义的情况下,我希望将数据当作数组结构使用 struct ArrayOfPacket { long[]

我从一个IntPtr开始,它从发送周期性数据包的硬件源发送结构化数据。线程从Intptr缓冲区复制数据包,并将字节[]放入队列。稍后读取队列,字节[]转换为使用的结构,并成为数据包类型的集合(数组)

struct Packet {
  long time;
  int field1;
  short field2;
}

Packet[] array_of_packet; 
在不重复结构定义的情况下,我希望将数据当作数组结构使用

struct ArrayOfPacket {
  long[] time;
  int[] field1;
  short[] field2;
}

ArrayOfPacket data;  
此格式允许其他函数将其用作向量:

Plot(data.time, data.field1);

如果您想要的只是一种转换为阵列的简单方法,那么只需使用LINQ:

Plot (array_of_packet.Select(p => p.time).ToArray(),
      array_of_packet.Select(p => p.field1).ToArray());
如果您正在寻找一种神奇的方法来重新排列内存中的数据,而不必花费复制成本,那么您就不走运了。;-)

使用Linq非常简单

data.time = array_of_packet.Select(p => p.time).ToArray();
data.field1 = array_of_packet.Select(p => p.field1).ToArray();
data.field2 = array_of_packet.Select(p => p.field2).ToArray();
尽管您需要将属性
公开

一个更有效的解决方案可能是

var time = new long[array_of_packet.Length];
var field1 = new int[array_of_packet.Length];
var field2 = new short[array_of_packet.Length];
for(int i = 0; i < array_of_packet.Length; i++)
{
    time[i] = array_of_paket[i].time;
    field1[i] = array_of_paket[i].field1;
    field2[i] = array_of_paket[i].field2;
}

data.time = time;
data.field1 = field1;
data.field2 = field2;
var time=new long[array_of_packet.Length];
var field1=新整数[数据包的数组长度];
var field2=新的短[array_of_packet.Length];
for(int i=0;i
您可以创建一个包装类,公开类似数组的访问器语法:

class ArrayWrapper<T, TField>
{
    Func<T, TField> getField;
    T[] array;

    public ArrayWrapper(T[] array, Func<T, TField> getField)
    {
        this.array = array;
        this.getField = getField;
    }

    public TField this[int index]
    {
        get { return this.getField(this.array[index]);}
    }

}
。。。可以按照您想要的方式使用:

Plot(data.time, data.field1);
根据您的具体需要,您可以通过多种方式对此进行详细说明:

  • 使类实现一个类似于
    IList
    的接口,这样
    Plot()
    就可以以一种与底层类型无关的方式编写。(阵列已实现IList)
  • 如果性能是高优先级的,而不是使用委托(
    Func
    ),则可以将
    其中T是struct
    添加到
    ArrayWrapper
    定义中,并让
    ArrayWrapper
    将字节偏移量作为其构造函数参数,并执行一些
    unsafe
    magic以更快地访问字段数据

我输了!无论如何,它应该是长时间的,而不是长时间的。好吧,那是一个完全不同的布局。你需要逐项手动复制所有内容。你真的应该研究创建。当我问这个问题时-这就是我要找的-@brainfog:我想可能是。我喜欢LINQ,但听起来你好像在试图避免将数据复制到多个数组中。起初我是以一种循序渐进的方式考虑的:1)收集数据2)转换为struct和数组3)转换为数组结构,而无需重新键入原始结构(因为我有很多数组,以后可能会更改)
var data = new
{
    time = Wrap(array_of_packet, p => p.time),
    field1 = Wrap(array_of_packet, p => p.field1),
    field2 = Wrap(array_of_packet, p => p.field2)
};
Plot(data.time, data.field1);