Clear Filters
Clear Filters

Can a custom argument validation function alter the field names of its input variable?

4 views (last 30 days)
I'm making a function that takes a scalar or non-scalar struct as one of its inputs, and this struct needs to have 3 fields with specific names: "PD", "RED", and "IR". However, I'm not the only one using this function, and I don't want it to return errors if the user inputs a struct with slightly different field names like "pd" or "Red" or "IR_value".
Usually the input struct itself will be made with a command such as:
inputstruct = struct('PD',{1,2}, 'red',{1,3}, 'ir',{2,4});
In a previous version of this function, I had a nested set of for loops and if statements checking that the input struct's field names at least contain "PD", "RED", or "IR" (ignoring case), and if so, altering the struct fields to exacly match the desired field names if they don't already. There may be other ways of handling this, but so far I've found that altering the field names to match the exact text I want them to be inside the function really helps simplify things when calling values from the input struct later on.
In the current version of my function, I'm trying to add argument validation, and I was wondering if a custom validation function could handle this part of my code.
So my question is: aside from confirming the class and size of my input struct, could I make an argument validation function that "corrects" the struct field names to what they need to be for the rest of the function to work?
So far I can't find a way to make that happen - whenever I step out of the argument validation function, the changes I try to make get undone. I'm not sure if that means I haven't found the right syntax or if argument validation functions simply aren't capable of that sort of thing.
Thanks for the help.

Accepted Answer

Stephen23
Stephen23 on 22 Apr 2024
Edited: Stephen23 on 22 Apr 2024
The hard part is not validation, but mapping random fieldnames to your desired fieldnames.
Notet that argument validation does not return any values nor does it allow any changes to be made to the workspace, so probably the easiest approach is to simply map the fieldnames after argument validation.
Here is one approach which finds the permutation of fieldnames that minimizes the norm of the edit distances:
inp = struct('Red',{1,2}, 'pd',{8,9}, 'IR_value',{2,4})
inp = 1x2 struct array with fields:
Red pd IR_value
ifn = fieldnames(inp);
ofn = {'PD';'RED';'IR'};
pfn = ofn(perms(1:3));
prv = Inf;
rpl = NaN;
for k = 1:size(pfn,1)
row = pfn(k,:);
tmp = cellfun(@editDistance,ifn,row(:));
dst = sum(tmp.^2);
if dst<prv
rpl = row;
prv = dst;
end
end
rpl
rpl = 1x3 cell array
{'RED'} {'PD'} {'IR'}
out = cell2struct(struct2cell(inp),rpl,1)
out = 1x2 struct array with fields:
RED PD IR
Checking:
out.RED
ans = 1
ans = 2
out.PD
ans = 8
ans = 9
out.IR
ans = 2
ans = 4
I would strongly recommend that you add some limits to the maximum allowed edit distance (both for any individual fieldname as well as for the overall norm). You could also add a check that ensures that the desired text is always contained within the input fieldnames, e.g.:
fnh = @(a,b)contains(a,b,'IgnoreCase',true);
if dst<prv && all(cellfun(fnh,ifn,row(:)))
You could also play around with the product of the edit distances (rather than the norm). It all depends on how different you want to permit the differences to be and how interdependent you want the mapping to be.
  2 Comments
Steven Lord
Steven Lord on 22 Apr 2024
The hard part is not validation, but mapping random fieldnames to your desired fieldnames.
And deciding how to handle ambiguous cases. [A surprising percentage of the time for design reviews I participate in at MathWorks get taken up by "How should we handle this ambiguous case?"]
If the "special" fieldnames include both RED and IR, which of those special fieldnames should be populated if the original struct contained a field INSPIRED? Or if that name has too much "extra stuff", how about TIRED?
Michael Butler
Michael Butler on 22 Apr 2024
Notet that argument validation does not return any values nor does it allow any changes to be made to the workspace, so probably the easiest approach is to simply map the fieldnames after argument validation.
This is what I needed, thanks. Interesting what you showed for edit distances on field names, I'd never heard of that before. I've already got statements to catch errors similar to your 'INSPIRED' or 'TIRED' cases. I also instruct other users about formatting the field names, so in this particular case it's enough for us to use 'contains' and 'matches' statements to account for upper/lowercase characters.

Sign in to comment.

More Answers (0)

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!