在非标量结构matlab中查找字符串
find string in non-scalar structure matlab
这是 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' 的实际内容执行 'grep'多变的)?
目的是看'quick and dirtily'结构中是否存在一个字符串(不管在什么地方)换句话说(针对Linux用户) : 我想在 matlab 变量上使用 'grep'。
我试过arrayfun(@(x) any(strcmp(x, 'treasure')), s)
没有成功,输出:
ans =
1×3 logical array
0 0 0
这是避免显式循环的一种方法
% 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)));
..如果您对出现的次数不感兴趣
一种通用方法(适用于任何结构数组 s
)是使用 struct2cell
, test if the contents of any of the cells are equal to the string 'treasure'
, and recursively repeat the above for any cells that contain structures. This can be done in a 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!
取决于你的真实数据的格式,如果你能找到包含你的字符串的字符串:
any( ~cellfun('isempty',strfind( arrayfun( @(x)[x.ad.treasurehunt],s,'uni',0 ) ,str)) )
这是 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' 的实际内容执行 'grep'多变的)?
目的是看'quick and dirtily'结构中是否存在一个字符串(不管在什么地方)换句话说(针对Linux用户) : 我想在 matlab 变量上使用 'grep'。
我试过arrayfun(@(x) any(strcmp(x, 'treasure')), s)
没有成功,输出:
ans =
1×3 logical array
0 0 0
这是避免显式循环的一种方法
% 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)));
..如果您对出现的次数不感兴趣
一种通用方法(适用于任何结构数组 s
)是使用 struct2cell
, test if the contents of any of the cells are equal to the string 'treasure'
, and recursively repeat the above for any cells that contain structures. This can be done in a 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!
取决于你的真实数据的格式,如果你能找到包含你的字符串的字符串:
any( ~cellfun('isempty',strfind( arrayfun( @(x)[x.ad.treasurehunt],s,'uni',0 ) ,str)) )