如何初始化Matlab结构数组以进行增长?

时间:2018-08-26 03:06:40

标签: matlab struct

增长数组,例如在Matlab编程中通常不赞成通过x = [x, a]进行循环访问,因为它会导致一个或多个调整大小的操作,因此预分配通常是更好的选择。但是,在某些情况下,例如作为parfor块中的reduction assignment,它可能具有优势。为此,必须将数组创建为零大小。对于数字数组,表达式为[],对于单元格数组为{}

对于struct数组,它不是很清晰。例如,初始化为struct()不会创建大小为零的结构数组,而是创建没有字段的1x1结构数组。这会导致错误

  

使用horzcat时出错
  连接的结构数组中的字段数不匹配。
  结构数组的串联要求这些数组具有相同的字段集。

在增长过程中,因为附加结构的字段结构与“无字段”结构不兼容。

如何初始化零大小的结构数组以进行增长?

2 个答案:

答案 0 :(得分:2)

事实证明,答案是初始化为零大小的数字数组x = []。即使它不是结构数组,但通过a附加结构x = [x, a]也会生成1x1结构数组,可以将具有相同字段的其他结构附加到该数组中。

这种不直观的行为似乎是Matlab语言的一般怪癖,因为[]是“灵活类型”的。最初是一个零大小的双精度数组,但附加单值使其成为单个数组,附加单元格数组使它成为一个单元数组。

正如@LuisMendo在评论中指出的那样,struct([])直接给出一个零字段的结构数组,没有任何字段。首选此语法,因为它不太模糊。此外,s = struct('field1', {}, 'field2', {})可用于创建具有定义字段的零尺寸结构数组。


我刚刚发现,@ CrisLuengo的注释中的建议(通过分配附加到end + 1而不是串联)在“初始化成长”问题的背景下不起作用。分配不能更改由其字段定义的结构的“类型”。从无字段更改为要附加的任何结构的字段会导致错误“不同结构之间的下标分配”。 (但请参阅他的评论和我的回答以作澄清)

答案 1 :(得分:1)

通过串联增长数组

x = [x, 0];

非常慢,请参见herehere。相反,应该(如果由于某种原因无法进行预分配),通过添加一个新元素来增加数组,如下所示:

x(end+1) = 0;

原因是[x,0]在每次循环迭代时创建一个新数组,将旧数据复制到其中,而另一种形式则扩展了该数组,仅偶尔需要重新分配(它会使基础内存大小加倍。数组变得太小)。

要初始化一个空的结构数组(如suggested by @LuisMendo in a comment),可以这样做:

s = struct('field1', {}, 'field2', {});

要附加到它,请执行以下操作:

s(end+1) = struct('field1', 1, 'field2', 'x');

或者,可以附加

s(end+1).field1 = 5;
s(end).field2 = 'y';

请注意,在这种情况下,end+1仅在第一次向数组中添加新元素时发生,随后的字段将写入最后一个数组元素。