Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

isfield sub-fields question and loading field without switch statement

1 view
Skip to first unread message

Dante Passmore

unread,
Nov 24, 2009, 4:56:23 PM11/24/09
to
Hi all,

Two easy questions for you that I could not find an answer to:

1)
I am sorting data into several sub-fields, such as A.B.C.D1 through A.B.C.D5
Now if I want to load A.B.C.D4 I need to use isfield to check if it exists first (I want to avoid all red text errors!). Is there an easier way to do this rather than use isfield 4 times for A, then A.B, then A.B.C and then A.B.C.D4?

2)
Now lets say that I wrote a generic routine that takes in a flag as an argument, and depending on that flag it will save data into field A.B.C.D# where # will be between 1-5. I know this can be done by:

A.B.C.(set_field) = data;

Where set_field is a string containing "D#" but what if I have a separate function that needs to load this data later? This does not seem to work:

get_data = A.B.C.(load_field)

I realize that I could make a big switch statement, but that seems rather ugly compared to just passing in a variable containing the proper string.


Thanks for the help!

----D

Jan Simon

unread,
Nov 25, 2009, 6:53:06 AM11/25/09
to
Dear Dante!

> 1)
> I am sorting data into several sub-fields, such as A.B.C.D1 through A.B.C.D5
> Now if I want to load A.B.C.D4 I need to use isfield to check if it exists first (I want to avoid all red text errors!). Is there an easier way to do this rather than use isfield 4 times for A, then A.B, then A.B.C and then A.B.C.D4?

try
Data = A.B.C.D4;
catch
Data = DefaultValue;
end

or:
quest = struct('type', '.', 'subs', {'B', 'C', 'D'});
try
Data = subsref(A, quest);
catch
Data = DefaultValue;
end

> 2)
> Now lets say that I wrote a generic routine that takes in a flag as an argument, and depending on that flag it will save data into field A.B.C.D# where # will be between 1-5. I know this can be done by:
>
> A.B.C.(set_field) = data;
>
> Where set_field is a string containing "D#" but what if I have a separate function that needs to load this data later? This does not seem to work:
>
> get_data = A.B.C.(load_field)

"Does not seem to work" is not descriptive. Actually this works if the variable "load_field" is e.g. the string 'D1'. Again you can work with TRY-CATCH.

Good luck, Jan

Matt

unread,
Nov 25, 2009, 8:03:21 AM11/25/09
to
Below are some functions that I used to use for this kind of thing before the days of dynamic fieldnames (or at least before I was aware of them). It combines Jan's try...catch idea with eval()

I never find use for them anymore and, on the whole, I find it wise to avoid deep nesting of structures.


function Y=getfld(S,fieldpath)
%A somewhat enhanced version of getfield() allowing one to get
%field values in subfields of the structure/object S by specifying the FIELDPATH.
%
%Usage: getfld(S,'s.f') will get S.s.f
%
%Works for any object capable of a.b.c.d ... subscripting
%
%Currently, only single structure input is supported, not structure arrays.


cmdstr=['S.' fieldpath ';'];


try
Y=eval(cmdstr);
catch
error 'Bad fieldpath';
end

function S=setfld(S,fieldpath,V)
%A somewhat enhanced version of setfield() allowing one to set
%fields in substructures of structure/object S by specifying the FIELDPATH.
%
%Usage: setfld(S,'s.f',V) will set S.s.f=V
%
%
%%Note that for structure S, setfield(S.s,'f') would crash with an error if
%S.s did not already exist. Moreover, it would return a modified copy
%of S.s rather than a modified copy of S, behavior which would often be
%undesirable.
%
%
%Works for any object capable of a.b.c.d ... subscripting
%
%Currently, only single structure input is supported, not structure arrays.


try
eval(['S.' fieldpath '=V;']);
catch
error 'Something''s wrong.';
end

Jos (10584)

unread,
Nov 25, 2009, 8:11:23 AM11/25/09
to
"Dante Passmore" <drpas...@gmail.com> wrote in message <hehkq7$8jq$1...@fred.mathworks.com>...

> Hi all,
>
> Two easy questions for you that I could not find an answer to:
>
> 1)
> I am sorting data into several sub-fields, such as A.B.C.D1 through A.B.C.D5
> Now if I want to load A.B.C.D4 I need to use isfield to check if it exists first (I want to avoid all red text errors!). Is there an easier way to do this rather than use isfield 4 times for A, then A.B, then A.B.C and then A.B.C.D4?

You could use a try-catch statement as explained before, or use logical short-circuit operators:

if exist('A','var') && isfield(A,'B') && isfield(A.B,'C') && isfield(A.B.C, 'D4')
disp('yep')
else
disp(':-(')
end

If one of the sub-conditions is false, the remainder of the if condition is skipped

> 2)
> Now lets say that I wrote a generic routine that takes in a flag as an argument, and depending on that flag it will save data into field A.B.C.D# where # will be between 1-5. I know this can be done by:
>
> A.B.C.(set_field) = data;
>
> Where set_field is a string containing "D#" but what if I have a separate function that needs to load this data later? This does not seem to work:
>
> get_data = A.B.C.(load_field)
>
> I realize that I could make a big switch statement, but that seems rather ugly compared to just passing in a variable containing the proper string.

I am a little lost here. What is not working?

x = 'D4'
A.B.C.(x) = 10 ;
y = 'D4'
v = A.B.C.(y)

hth
Jos

0 new messages