Here's a non-scalar structure in matlab:
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
is there an easy way to test if the structure s
contains the string 'treasure' without having to loop through every field (e.g. doing a 'grep' through the actual content of the variable)?
The aim is to see 'quick and dirtily' whether a string exists (regardless of where) in the structure. In other words (for Linux users): I'd like to use 'grep' on a matlab variable.
I tried arrayfun(@(x) any(strcmp(x, 'treasure')), s)
with no success, output:
ans =
1×3 logical array
0 0 0
One general approach (applicable to any structure array s
) is to convert your structure array to a cell array using 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 that stops if either the string is found or there are no structures left to recurse through. Here's the solution implemented as a function:
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
And using your sample structure s
:
>> string_hunt(s, 'treasure')
ans =
logical
1 % True!