5

私はしばしば次のようなことをしていることに気づきました:

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');

連結するのではなく、ベクトル スロットを埋めるようにループを変更します。

後で構造体またはオブジェクトを保持できるように、ベクトルを事前に割り当てる方法はありますか?


更新: Azim の回答に触発されて、ループの順序を単純に逆にしました。最後の要素を最初に処理すると、デバッガーが確認するように、最初のヒットでベクター全体の事前割り当てが強制されます。

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()、MATLABprocessedDataが実際のオブジェクトでの最初の書き込みで初期化するため、 によって返されるすべてのオブジェクトが有効な引数なしのコンストラクターを持っている必要があります。

mlint配列の増加の可能性についてまだ不平を言っていますが、それは逆ループの反復を認識できないためだと思います...

4

3 に答える 3

5

Azimの回答に加えて、これを行う別の方法は次を使用することですrepmat:

% Make a single structure element:
processedData = struct('field1',[],'field2',[]);
% Make an object:
processedData = object_constructor(...);
% Replicate data:
processedData = repmat(processedData,1,nElements);

ここnElementsで、構造体またはオブジェクト配列に含まれる要素の数です。

注意: 作成しているオブジェクトがハンドル クラスから派生している場合は、オブジェクト自体を複製するのではなく、オブジェクトへの参照を処理するだけです。実装によっては、オブジェクト コンストラクター メソッドをnElements何度も呼び出す必要がある場合があります。

于 2009-02-26T18:18:38.027 に答える
3

構造体のフィールドとprocessedData長さがわかっているので、1 つの方法は次のようになります。

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

于 2009-02-26T17:33:12.923 に答える
3

struct適切なサイズのcell 配列を渡すことができます。

processedData = struct('field1', cell(nElements, 1), 'field2', []);

これにより、セル配列と同じサイズの構造体配列が作成されます。

于 2009-03-02T16:37:56.050 に答える