我有一个包含某些字段的结构数组。现在我想过滤某些字段为空的所有行。
基本上我现在拥有的是:
data(1).elem1 = 1;
data(1).elem2 = 2;
data(1).elem3 = 3;
data(2).elem1 = 4;
data(2).elem3 = 6;
data(3).elem1 = 7;
data(3).elem2 = 8;
data(4).elem1 = 9;
data(4).elem2 = 10;
data(4).elem3 = 11;
data(5).elem1 = 9;
data(5).elem3 = 11;
data
fields = {'elem2,elem3'};
data(any(~cellfun(@(x) any(~isempty(x)), {data.('elem2'); data.('elem3')}))) = [];
这没关系。但是,我不想具体表达{data.('elem2'); data.('elem3')}
。我想简单地使用变量fields
。
我可以遍历字段并创建一个包含{data.('elem2'); data.('elem3')}
的临时变量。但是我不想这样做。因为我认为有一种更聪明的方式,我想知道它是否能像我现在所做的更有效率。
答案 0 :(得分:2)
您可以将结构转换为单元格,并使用cellfun
检查任何字段的空值。然后使用ismember
查找要检查的字段的索引。
fields = {'elem2','elem3'};
emptyIdx = squeeze(cellfun('isempty', struct2cell(data)));
idxToRemove = any(emptyIdx(ismember(fieldnames(data), fields),:), 1);
示例:
data(1).elem1 = 1;
data(1).elem2 = 2;
data(1).elem3 = 3;
data(2).elem1 = 4;
data(2).elem3 = 6;
data(3).elem1 = 7;
data(3).elem2 = 8;
data(4).elem1 = 2;
data(4).elem3 = 5;
data(4).elem2 = 4;
仅为索引1和4提供数据结构
data =
1x2 struct array with fields:
elem1
elem2
elem3
答案 1 :(得分:0)
这是一种做法
I=ismember(fieldnames(data), {'elem2', 'elem3'});
data(~arrayfun(@(x) any(I & structfun(@isempty, x)), data))=[];
找到感兴趣的字段的索引。使用data
迭代arrayfun
的所有元素,然后使用structfun
迭代所有字段,并忽略I & ...
对我们不感兴趣的字段。