增长数组,例如在Matlab编程中通常不赞成通过x = [x, a]
进行循环访问,因为它会导致一个或多个调整大小的操作,因此预分配通常是更好的选择。但是,在某些情况下,例如作为parfor
块中的reduction assignment,它可能具有优势。为此,必须将数组创建为零大小。对于数字数组,表达式为[]
,对于单元格数组为{}
。
对于struct数组,它不是很清晰。例如,初始化为struct()
不会创建大小为零的结构数组,而是创建没有字段的1x1结构数组。这会导致错误
使用horzcat时出错
连接的结构数组中的字段数不匹配。
结构数组的串联要求这些数组具有相同的字段集。
在增长过程中,因为附加结构的字段结构与“无字段”结构不兼容。
如何初始化零大小的结构数组以进行增长?
答案 0 :(得分:2)
事实证明,答案是初始化为零大小的数字数组x = []
。即使它不是结构数组,但通过a
附加结构x = [x, a]
也会生成1x1结构数组,可以将具有相同字段的其他结构附加到该数组中。
这种不直观的行为似乎是Matlab语言的一般怪癖,因为[]
是“灵活类型”的。最初是一个零大小的双精度数组,但附加单值使其成为单个数组,附加单元格数组使它成为一个单元数组。
正如@LuisMendo在评论中指出的那样,struct([])
直接给出一个零字段的结构数组,没有任何字段。首选此语法,因为它不太模糊。此外,s = struct('field1', {}, 'field2', {})
可用于创建具有定义字段的零尺寸结构数组。
我刚刚发现,@ CrisLuengo的注释中的建议(通过分配附加到end + 1
而不是串联)在“初始化成长”问题的背景下不起作用。分配不能更改由其字段定义的结构的“类型”。从无字段更改为要附加的任何结构的字段会导致错误“不同结构之间的下标分配”。
(但请参阅他的评论和我的回答以作澄清)
答案 1 :(得分:1)
通过串联增长数组
x = [x, 0];
非常慢,请参见here和here。相反,应该(如果由于某种原因无法进行预分配),通过添加一个新元素来增加数组,如下所示:
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
仅在第一次向数组中添加新元素时发生,随后的字段将写入最后一个数组元素。