这是matlab中的non-scalar structure:
clearvars s
s=struct;
for id=1:3
s(id).wa='nko';
s(id).test='5';
s(id).ad(1,1).treasurehunt='asdf'
s(id).ad(1,2).treasurehunt='as df'
s(id).ad(1,3).treasurehunt='foobar'
s(id).ad(2,1).treasurehunt='trea'
s(id).ad(2,2).treasurehunt='foo bar'
s(id).ad(2,3).treasurehunt='treasure'
s(id).ad(id,4).a=magic(5);
end
是否有一种简单的方法来测试结构s
是否包含字符串'treasure'而不必遍历每个字段(例如,通过变量的实际内容执行'grep')?
目的是看到“快速而肮脏”的结构中是否存在字符串(无论在何处)。换句话说(对于Linux用户):我想使用'grep '在matlab变量上。
我尝试arrayfun(@(x) any(strcmp(x, 'treasure')), s)
没有成功,输出:
ans =
1×3 logical array
0 0 0
答案 0 :(得分:2)
这是避免显式循环的一种方法
% Collect all the treasurehunt entries into a cell with strings
s_cell={s(1).ad.treasurehunt, s(2).ad.treasurehunt, s(3).ad.treasurehunt};
% Check if any 'treasure 'entries exist
find_treasure=nonzeros(strcmp('treasure', s_cell));
% Empty if none
if isempty(find_treasure)
disp('Nothing found')
else
disp(['Found treasure ',num2str(length(find_treasure)), ' times'])
end
请注意,您也可以这样做
% Collect all the treasurehunt entries into a cell with strings
s_cell={s(1).ad.treasurehunt, s(2).ad.treasurehunt, s(3).ad.treasurehunt};
% Check if any 'treasure 'entries exist
find_treasure=~isempty(nonzeros(strcmp('treasure', s_cell)));
..如果您对出现次数不感兴趣
答案 1 :(得分:2)
一种通用方法(适用于任何结构数组s
)是使用struct2cell
将结构数组转换为单元格数组,测试任何单元格are equal的内容是否为字符串'treasure'
,并递归地重复上面包含结构的任何单元格。这可以在while loop中完成,如果找到了字符串或者没有剩余的结构可以通过它停止。以下是作为函数实现的解决方案:
function found = string_hunt(s, str)
c = reshape(struct2cell(s), [], 1);
found = any(cellfun(@(v) isequal(v, str), c));
index = cellfun(@isstruct, c);
while ~found && any(index)
c = cellfun(@(v) {reshape(struct2cell(v), [], 1)}, c(index));
c = vertcat(c{:});
found = any(cellfun(@(c) isequal(c, str), c));
index = cellfun(@isstruct, c);
end
end
使用您的示例结构s
:
>> string_hunt(s, 'treasure')
ans =
logical
1 % True!
答案 2 :(得分:1)
取决于实际数据的格式,以及是否可以找到包含字符串的字符串:
any( ~cellfun('isempty',strfind( arrayfun( @(x)[x.ad.treasurehunt],s,'uni',0 ) ,str)) )