0

構造体の配列をフィールドごとに編集しようとするたびに、数週間かけて Matlab を実際に学習する必要があることに気付きます。現在、構造体の配列があり、各構造体には次の行に沿ったフィールドがあります。

x.fruit, x.color, x.season, x.source, x.flibbertigibbet

これらの各フィールドは文字列です。文字列のセル配列もあります。

y = {'リンゴ', 'バナナ', '花崗岩のヤシ'}

x.fruit が y にあるすべての構造体 (egxfruit == 'apple') を削除したいのですが、y をループする以外にこれを行う方法が見つからないようです。

私は次のようなことを望んでいました:

bad_idx = [x(:).fruit in y];
x(bad_idx) = [];

これは実行可能ですか?これを行うために cellfun を使用する方法はありますか?

4

1 に答える 1

1

の各要素にフィールドxの文字列のみが含まれているfruit場合は、次の方法で簡単に行うことができます。

toremove = ismember({x.fruit}, 'apple')
x(toremove) = [];

またはもっと簡単に

x = x(~ismember({x.fruit}, 'apple'));

この{x.fruit}構文は、fruitfor eachのすべての値をstructセル配列に結合します。次に、文字列のセル配列で を使用ismemberして、それぞれを と比較でき'apple'ます。xこれにより、へのインデックス付けに使用できるのサイズの論理配列が生成されxます。

strcmp上記の代わりに次のようなものを使用することもできますismember

x = x(~strcmp({x.fruit}, 'apple'));

アップデート

それぞれx(k).fruitに cell 配列が含まれている場合は、上記のアプローチと同様のアプローチを と組み合わせて使用​​できますcellfun

x(1).fruit = {'apple', 'orange'};
x(2).fruit = {'banana'};
x(3).fruit = {'grape', 'orange'};

x = x(~cellfun(@(fruits)ismember('apple', fruits), {x.fruit}));

%// 1 x 2 struct array with fields: 
%//     fruit

複数の種類の果物を一度に削除することを確認したい場合は、次のようにすることができます。

%// Remove if EITHER 'apple' or 'banana'
tocheck = {'apple', 'banana'};
x = x(~cellfun(@(fruits)any(ismember({'apple', 'banana'}, fruits)), {x.fruit}));

%// Remove if BOTH 'apple' and 'banana' in one
x = x(~cellfun(@(fruits)all(ismember({'apple', 'banana'}, fruits)), {x.fruit}));
于 2016-05-17T16:46:04.157 に答える