我经常发现自己在做这样的事情:
unprocessedData = fetchData(); % returns a vector of structs or objects
processedData = []; % will be full of structs or objects
for dataIdx = 1 : length(unprocessedData)
processedDatum = process(unprocessedData(dataIdx));
processedData = [processedData; processedDatum];
end
虽然功能上不是最佳的,但processedData
向量在循环内部正在增长。甚至mlint
警告我,我应该考虑预先分配速度。
如果数据是int8
的向量,我可以这样做:
% preallocate processed data array to prevent growth in loop
processedData = zeros(length(unprocessedData), 1, 'int8');
并修改循环以填充向量槽而不是连接。
有没有办法预分配矢量,以便随后可以保存结构或对象?
更新:,我只是简单地颠倒了循环顺序。处理最后一个元素首先强制在第一次命中中预先分配整个向量,因为调试器确认:
unprocessedData = fetchData();
% note that processedData isn't declared outside the loop - this breaks
% it if it'll later hold non-numeric data. Instead we exploit matlab's
% odd scope rules which mean that processedData will outlive the loop
% inside which it is first referenced:
for dataIdx = length(unprocessedData) : -1 : 1
processedData(dataIdx) = process(unprocessedData(dataIdx));
end
这要求process()
返回的任何对象都有一个有效的零参数构造函数,因为MATLAB在第一次用真实对象写入时初始化processedData
。
mlint
仍抱怨可能的数组增长,但我认为这是因为它无法识别反向循环迭代......
答案 0 :(得分:5)
除了Azim's answer之外,另一种方法是使用repmat
:
% Make a single structure element:
processedData = struct('field1',[],'field2',[]);
% Make an object:
processedData = object_constructor(...);
% Replicate data:
processedData = repmat(processedData,1,nElements);
其中nElements
是结构或对象数组中的元素数。
注意:如果您正在创建的对象是从handle class派生的,那么您将不会复制对象本身,只需处理对它的引用。根据您的实现,您可能必须调用对象构造函数方法nElements
次。
答案 1 :(得分:3)
由于您知道结构processedData
的字段并且您知道其长度,因此可以采用以下方法:
unprocessedData = fetchData();
processedData = struct('field1', [], ...
'field2', []) % create the processed data struct
processedData(length(unprocessedData)) = processedData(1); % create an array with the required length
for dataIdx = 1:length(unprocessedData)
processedData(dataIdx) = process(unprocessedData(dataIdx));
end
这假设process
函数返回一个与processedData
字段相同的结构。
答案 2 :(得分:3)
您可以将单元格数组传递到适当大小的struct
:
processedData = struct('field1', cell(nElements, 1), 'field2', []);
这将生成一个与单元格数组大小相同的结构数组。