如何从 Matlab 数组中删除特定 struct.field 值的结构
How to remove structs from Matlab array for specific struct.field values
每次我尝试按字段编辑结构数组时,我发现我真的需要花几周的时间来尝试真正学习 Matlab。现在,我有一个结构数组,其中每个结构都有以下行的字段:
x.fruit, x.color, x.season, x.source, x.flibbertigibbet
这些字段中的每一个都是一个字符串。我还有一个字符串元胞数组:
y = {'apple', 'banana', 'palm of granite'}
我想删除所有 x.fruit 在 y 中的结构(例如 x.fruit == 'apple'),但似乎找不到其他方法而不是通过循环 y.
我希望得到类似以下内容的东西:
bad_idx = [x(:).fruit in y];
x(bad_idx) = [];
这可行吗?有没有办法使用 cellfun 来做到这一点?
如果 x
的每个元素仅包含 fruit
字段的字符串,您可以通过以下方式轻松实现。
toremove = ismember({x.fruit}, 'apple')
x(toremove) = [];
或更简短
x = x(~ismember({x.fruit}, 'apple'));
{x.fruit}
语法将每个 struct
的 fruit
的所有值组合到一个元胞数组中。然后,您可以在字符串元胞数组上使用 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}));
每次我尝试按字段编辑结构数组时,我发现我真的需要花几周的时间来尝试真正学习 Matlab。现在,我有一个结构数组,其中每个结构都有以下行的字段:
x.fruit, x.color, x.season, x.source, x.flibbertigibbet
这些字段中的每一个都是一个字符串。我还有一个字符串元胞数组:
y = {'apple', 'banana', 'palm of granite'}
我想删除所有 x.fruit 在 y 中的结构(例如 x.fruit == 'apple'),但似乎找不到其他方法而不是通过循环 y.
我希望得到类似以下内容的东西:
bad_idx = [x(:).fruit in y];
x(bad_idx) = [];
这可行吗?有没有办法使用 cellfun 来做到这一点?
如果 x
的每个元素仅包含 fruit
字段的字符串,您可以通过以下方式轻松实现。
toremove = ismember({x.fruit}, 'apple')
x(toremove) = [];
或更简短
x = x(~ismember({x.fruit}, 'apple'));
{x.fruit}
语法将每个 struct
的 fruit
的所有值组合到一个元胞数组中。然后,您可以在字符串元胞数组上使用 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}));