How do find and match specific elements in a structure?

67 views (last 30 days)
I want to write a local function that displays a vector of indices of the elements of structure S where a match is found between the key (search string) and the contents of the fields.
The function should also check whether the "key" is a character array or string, if "struct" is a structure array and if the "field" is a character array or string, and if it's name is spelled correctly. If any of this is not the case, a warning message should be displayed. If no specific field is given, all available fields should be searched by the function find_match.
I have posted what I have so far below, and attached the file with the structure S.
It works but not all results are correct.
Any help and hints are appreciated! Thanks!
load struct06A S
result=find_match('016',S)
% correct answer: 16 21 28 32
result=find_match(016,S)
% correct answer: warning message and empty result
result=find_match('Moha',S)
% correct answer: 2 6
result=find_match('moha',S)
% correct answer: 2 6
result=find_match('0663',S)
% correct answer: 2 4 7 19 20 22 23 25 29
result=find_match('0663',S,'scode')
% correct answer: 2 4 7 19 20 22 23 25 29
result=find_match('0663',S,'Scode')
% correct answer: warning message and empty result
result=find_match('sal',S,'name')
% correct answer: 25 26
result=find_match('016',S,'matnum')
% correct answer: 16 21 28 32
result=find_match('w',S,'gender')
% correct answer: 1 7 21 24 32
result=find_match('a',S,'gender')
% correct answer: empty result
result=find_match('y',S)
% correct answer: 6 19 20 27 31
function result=find_match(key,struct,field)
result = [];
F = fieldnames(struct);
flength = length(F);
%Check if input arguments key and struct are correct element type:
if isstring(key)||ischar(key)
if isstruct(struct)
disp('')
else
disp("The second input argument must be a structure array.")
end
else
disp("The first input argument must be a string or character array.")
end
%Check if input argument field is of correct type + is given as input
% and try to find the result
if nargin == 3
if isstring(field)||ischar(field)
try
Contents = lower(horzcat(struct.(field)));
result = find(contains(Contents,lower(string(key))));
catch
disp("The third input argument is not an existing field.")
end
end
else
for i = 1:flength
fields = string(F(i));
Contents = lower(horzcat(struct.(fields)));
r = horzcat(result,find(contains(Contents,lower(string(key)))));
result = unique(r);
end
end
return
end
  4 Comments
Jan
Jan on 2 May 2022
Omit the line "field=A", because you overwrite the input argument "field".
Avoid using the names of built-in functions as variables, because this causes unexpected behavior frequently. In your case use e.g. "S" instead of "struct".
Theresia Dannbauer
Theresia Dannbauer on 2 May 2022
Thank you Jan! I edited the code in my question to what I have right now.
Do you have any ideas for the for-loop? So that the loop actually does what it is supposed to do as specified in my first comment? Right now the code puts out "This field does not exist" for all inputs, even if it should not do anything because the field does exist!

Sign in to comment.

Answers (1)

Shivam
Shivam on 6 Oct 2023
Hi Theresia Dannbauer,
It is my understanding that through the "find_match" function, you want to check the existence of the "field" among all struct's fields. If "field" is not given as an argument to the "find_match" function, the "key" is to be searched in all existing fields' values.
You can follow the below workaround to achieve the requirement.
function result=find_match(key,S,field)
result = [];
%Check if input arguments key and struct are correct element type:
if isstring(key)||ischar(key)
if isstruct(S)
disp('')
else
disp("The second input argument must be a structure array.")
return; % To avoid further user of S
end
else
disp("The first input argument must be a string or character array.")
return; % To avoid further use of key
end
% Store fieldnames when S is struct
F = fieldnames(S);
flength = length(F);
%Check if input argument field is of correct type + is given as input
% and try to find the result
if nargin == 3
if isstring(field)||ischar(field)
% Check if field exists in S's fields.
if any(ismember(F, field))
Contents = lower(horzcat(S.(field)));
result = find(contains(Contents,lower(string(key))));
else
disp("The third input argument is not an existing field.")
end
end
else
for i = 1:flength
fields = string(F(i));
Contents = lower(horzcat(S.(fields)));
r = horzcat(result,find(contains(Contents,lower(string(key)))));
result = unique(r);
end
end
return
end
Also, use S as a struct parameter to avoid any unexpected behavior.
I hope it helps.

Categories

Find more on Structures in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!