在非标量结构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)) )