0

每次我尝试按字段编辑结构数组时,我发现我真的需要花几个星期的时间来尝试真正学习 Matlab。现在,我有一个结构数组,其中每个结构都有以下字段:

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

这些字段中的每一个都是一个字符串。我还有一个字符串单元数组:

y = {'苹果','香蕉','花岗岩棕榈'}

我想删除x.fruit在y中的所有结构(例如xfruit =='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包含一个元胞数组,那么您可以使用类似于上述方法的方法并结合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 回答