which function to us to check if a struct name exists

Dear all,
I am importing data in the form of a struct and the struct name is not the same everytime. Sometimes the struct is named a.b.c.d and sometimes it is named a.b.x.d. or a.b.c.x
I want to to perform a check if a.b.c.d exists before continueing the script.

1 Comment

Using the correct terminology would help you:
a.b.x.d
^ variable
^ field
^ field
^ field
There are multiple structures involved here (not one as you wrote), it helps to describe their relationship correctly.

Sign in to comment.

 Accepted Answer

Use function isfield

11 Comments

I tried this; but is fields is searching for content in the strcut and not for the existance of the struct name right?
a.b.c.d=1;
% a.b.x.d=[];
isfield(a.b.x.d)
Error:
Reference to non-existent field 'x'.
Error in testjestruct (line 5)
isfield(a.b.x.d)
You obviously didn't read carefully the function document.
a.b.c.d=1
a = struct with fields:
b: [1×1 struct]
isfield(a.b, 'x') && isfield(a.b.x, 'd') % check a.b.x.d exists
ans = logical
0
isfield(a.b, 'c') && isfield(a.b.c, 'd') % check a.b.c.d exists
ans = logical
1
a.b.c.d = 1;
a.b.x.d = 2;
a.b.c.x = 3;
One way to simplify the code above is to use getfield with a cell array that you grow with each new level, potentially combined with the fieldnames function. This way you wouldn't have to hard code something like a.b.c in your code.
f = {'b'};
aDotB = getfield(a, f{:})
aDotB = struct with fields:
c: [1×1 struct] x: [1×1 struct]
g = {'b', 'c'};
aDotBDotC = getfield(a, g{:})
aDotBDotC = struct with fields:
d: 1 x: 3
h = [g, 'd'];
result = getfield(a, h{:}) % Equivalent to a.b.c.d
result = 1
a.b.c.d
ans = 1
Why MATLAB can't extend the isfield (EDIT typo was getfield) function and dynamic field access with subfields? At least when the all intermediate non-grandchild are scalar?
isfield(a, 'b.c.d')
a.('b.c.d')
"Why MATLAB can't extend the getfield function and dynamic field access with subfields? "
Both GETFIELD and SETFIELD already work with arbitrarily nested structures (and not just scalar ones).
Sorry for typo; I meant ISFIELD not GETFIELD
@Bruno Luong: for consistency with GETFIELD and SETFIELD perhaps it could use the same syntax, e.g.:
isfield(a,'b','c','d') % proposed syntax
which can already be achieved using:
isf = false;
try
getfield(a,'b','c','d');
isf = true;
end
I don't think there's any technical reason why we couldn't extend isfield to handle that use case in some way, possibly by accepting an arbitrary number of inputs past the first (to mimic getfield and setfield.) If this worked would you use it?
a.b.c.d = 1;
isfield(a, 'b', 'c', 'd') % true
isfield(a, 'b', 'x', 'q') % false since b does not have a field x
I would be concerned with allowing something that looks like an indexing expression as the input to isfield -- would you expect something like this to work in that case? Having to parse the second input likely would make isfield quite a bit more complicated.
isfield(a, 'b(1).c(true).d')
I prefer the syntax with single input and nested field separate with the dot '.' character. I have made my own recusrive getfield ans setfield without try/catch, I might have an rrecursive isfield, just can't find it right now.
But for sure if there is a stock functions I'll use it instead.
a.b.c.d = 1;
isfieldx(a, 'b', 'c', 'd') % true
ans = logical
1
isfieldx(a, 'b', 'x', 'q') % false since b does not have a field x
ans = logical
0
function isf = isfieldx(s,varargin);
isf = false;
try
getfield(s,varargin{:});
isf = true;
end
end

Sign in to comment.

More Answers (1)

try/catch after reading your struct
try
data = a.b.c.d;
catch
try
data = a.b.x.d;
try
data = a.b.c.x;
catch
error('I''m too tired to try something else')
end
end
end

Categories

Products

Release

R2020b

Community Treasure Hunt

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

Start Hunting!