{"id":26,"date":"2006-03-08T11:26:01","date_gmt":"2006-03-08T16:26:01","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=26"},"modified":"2018-01-08T16:15:31","modified_gmt":"2018-01-08T21:15:31","slug":"working-with-structs","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2006\/03\/08\/working-with-structs\/","title":{"rendered":"Working with structs"},"content":{"rendered":"<style xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\">\r\n\r\npre.codeinput {\r\n  background: #F9F7F3;\r\n  padding: 10px;\r\n  border: 1px solid rgb(200,200,200);\r\n}\r\n\r\n@media print {\r\n  pre.codeinput {word-wrap:break-word; width:100%;}\r\n} \r\n\r\nspan.keyword {color: #0000FF}\r\nspan.comment {color: #228B22}\r\nspan.string {color: #A020F0}\r\nspan.untermstring {color: #B20000}\r\nspan.syscmd {color: #B28C00}\r\n\r\npre.codeoutput {\r\n  background: #F9F7F3;\r\n  color: #777777;\r\n  padding: 10px;\r\n  border: 1px solid rgb(200,200,200);\r\n}\r\n\r\npre.error {\r\n  color: red;\r\n}\r\n\r\np.footer {\r\n  text-align: right;\r\n  font-size: xx-small;\r\n  font-weight: lighter;\r\n  font-style: italic;\r\n  color: gray;\r\n}\r\n\r\n  <\/style><div xmlns:mwsh=\"https:\/\/www.mathworks.com\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\r\n   <introduction>\r\n      <p>MATLAB has some functions that are specifically designed for exploring the contents of structures (entities known in MATLAB\r\n         by the class <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/struct.html\"><tt>struct<\/tt><\/a>). I find the functions <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/isfield.html\"><tt>isfield<\/tt><\/a> and <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/fieldnames.html\"><tt>fieldnames<\/tt><\/a> particularly helpful.  The reason I raise this area of functionality is because some users new to MATLAB occasionally have\r\n         trouble finding these functions and try to use the function <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/exist.html\"><tt>exist<\/tt><\/a> to do the work for them and find it doesn't work out.\r\n      <\/p>\r\n   <\/introduction>\r\n   <h3>Contents<\/h2>\r\n   <div>\r\n      <ul>\r\n         <li><a href=\"#1\">Example Application<\/a><\/li>\r\n         <li><a href=\"#2\">snippet Help<\/a><\/li>\r\n         <li><a href=\"#3\">Sample Data<\/a><\/li>\r\n         <li><a href=\"#4\">Checking Inputs for Suitability with snippet with exist<\/a><\/li>\r\n         <li><a href=\"#9\">Try struct-specific functions<\/a><\/li>\r\n         <li><a href=\"#10\">Try snippet on Incorrect Inputs<\/a><\/li>\r\n         <li><a href=\"#11\">Try snippet with Good Inputs<\/a><\/li>\r\n         <li><a href=\"#12\">Extra Credit<\/a><\/li>\r\n      <\/ul>\r\n   <\/div>\r\n   <h3>Example Application<a name=\"1\"><\/a><\/h3>\r\n   <p>Suppose I'm writing an M-file to analyze data that I expect to come in a <tt>struct<\/tt> with two fields, named <tt>time<\/tt> and <tt>amplitude<\/tt>.  Since I intend to pass this M-file to lots of other folks, I want to write it somewhat carefully so errors the users make\r\n      give them enough information to correct problems without having to consult me too often.\r\n   <\/p>\r\n   <h3>snippet Help<a name=\"2\"><\/a><\/h3>\r\n   <p>Let's look at the help for our function first:<\/p><pre class=\"codeinput\">help <span class=\"string\">snippet<\/span>\r\n<\/pre><pre class=\"codeoutput\"> SNIPPET plots time vs. amplitude from an input struct.\r\n    SNIPPET(D) plots data from a struct D which must contain the two fields:\r\n            time : a sequence of times\r\n       amplitude : corresponding amplitudes\r\n    If either D.time or D.amplitude are missing, SNIPPET errors out.\r\n\r\n<\/pre><h3>Sample Data<a name=\"3\"><\/a><\/h3>\r\n   <p>Next let's get some data that is suitable for this function (<tt>ss<\/tt> and <tt>ssExtra<\/tt>), and some that is not (<tt>ssBad<\/tt>).\r\n   <\/p><pre class=\"codeinput\">sunspots = load(<span class=\"string\">'sunspot.dat'<\/span>);\r\nss.time = sunspots(:,1);\r\nss.amplitude = sunspots(:,2);\r\nssBad.time = ss.time;\r\nssBad.amp = ss.amplitude;\r\nssExtra = ss;\r\nssExtra.other = datestr(today);\r\n<\/pre><h3>Checking Inputs for Suitability with snippet with exist<a name=\"4\"><\/a><\/h3>\r\n   <p>Let's explore how I might check our different versions of the sunspot data to see which one or ones is suitable for use with\r\n      <tt>snippet<\/tt> so I can figure out what code to put into <tt>snippet<\/tt> to do the error checking. Remember, we want to check to see if the input is a <tt>struct<\/tt> and, if so, that it has fields <tt>time<\/tt> and <tt>amplitude<\/tt>. I'll begin by trying <tt>exist<\/tt>, and I am placing the code inside a <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/try.html\">try-catch<\/a>. so I can capture any errors and easily show them.\r\n   <\/p><pre class=\"codeinput\"><span class=\"keyword\">try<\/span>\r\n    exist(ss.time)\r\n<span class=\"keyword\">catch<\/span>\r\n    err = lasterror;\r\n    disp(err.message)\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeoutput\">Error using ==&gt; exist\r\nThe first input to exist is a string.\r\n<\/pre><p>That didn't work because <tt>exist<\/tt> expects string input.  So here's my next attempt.\r\n   <\/p><pre class=\"codeinput\"><span class=\"keyword\">try<\/span>\r\n    exist(<span class=\"string\">'ss.time'<\/span>)\r\n<span class=\"keyword\">catch<\/span>\r\n    err = lasterror;\r\n    disp(err.message)\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     0\r\n\r\n<\/pre><p>and that didn't work either!  What went wrong?  I gave <tt>exist<\/tt> a string input.  Looking at the help carefully, I see that the name I give must be a variable name or the name of some file\r\n      or method.  So now let me check my variable name using the function <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/isvarname.html\"><tt>isvarname<\/tt><\/a>.\r\n   <\/p><pre class=\"codeinput\">isvarname(<span class=\"string\">'ss.time'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     0\r\n\r\n<\/pre><p>I can also see what variables I do have in my workspace:<\/p><pre class=\"codeinput\">whos\r\n<\/pre><pre class=\"codeoutput\">  Name           Size                    Bytes  Class\r\n\r\n  ans            1x1                         1  logical array\r\n  err            1x1                      2158  struct array\r\n  f              1x25                      200  double array\r\n  fibo           1x25                      200  double array\r\n  n              1x1                         8  double array\r\n  nmax           1x1                         8  double array\r\n  sbad           1x1                      4856  struct array\r\n  spots        288x2                      4608  double array\r\n  ss             1x1                      4856  struct array\r\n  ssBad          1x1                      4856  struct array\r\n  ssExtra        1x1                      5002  struct array\r\n  sunspots     288x2                      4608  double array\r\n\r\nGrand total is 3969 elements using 31361 bytes\r\n\r\n<\/pre><p>and I see that I have <tt>ss<\/tt> but not <tt>ss.time<\/tt> because <tt>ss.time<\/tt> is a member of the <tt>struct<\/tt> but not a variable itself.  I've seen this confusion between structures, their fields, and variables, fairly regularly on\r\n      the <a>MATLAB newsgroup<\/a>.\r\n   <\/p>\r\n   <h3>Try struct-specific functions<a name=\"9\"><\/a><\/h3>\r\n   <p>I now understand that I have to look at the details of the structure variables to see if the fields I need are there.  Here's\r\n      the code I wrote:\r\n   <\/p><pre class=\"codeinput\">type <span class=\"string\">snippet<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction snippet(D)\r\n%SNIPPET plots time vs. amplitude from an input struct.\r\n%   SNIPPET(D) plots data from a struct D which must contain the two fields:\r\n%           time : a sequence of times\r\n%      amplitude : corresponding amplitudes\r\n%   If either D.time or D.amplitude are missing, SNIPPET errors out.\r\n\r\nif ~isstruct(D) || ...\r\n    ~(isfield(D,'time') &amp;&amp; isfield(D,'amplitude'))\r\n    error('snippet:incorrectInput', ...\r\n        'snippet expects a struct with fields time and amplitude');\r\nend\r\nplot(D.time,D.amplitude)\r\n<\/pre><h3>Try snippet on Incorrect Inputs<a name=\"10\"><\/a><\/h3><pre class=\"codeinput\"><span class=\"keyword\">try<\/span>\r\n    snippet(sunspots)\r\n<span class=\"keyword\">catch<\/span>\r\n    err = lasterror;\r\n    disp(err.message)\r\n<span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">try<\/span>\r\n    snippet(ssBad)\r\n<span class=\"keyword\">catch<\/span>\r\n    err = lasterror;\r\n    disp(err.message)\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeoutput\">Error using ==&gt; snippet\r\nsnippet expects a struct with fields time and amplitude\r\nError using ==&gt; snippet\r\nsnippet expects a struct with fields time and amplitude\r\n<\/pre><h3>Try snippet with Good Inputs<a name=\"11\"><\/a><\/h3>\r\n   <p>I leave it as an exercise for you to show that <tt>snippet<\/tt> runs correctly using either <tt>ss<\/tt> or <tt>ssExtra<\/tt> as inputs.\r\n   <\/p>\r\n   <h3>Extra Credit<a name=\"12\"><\/a><\/h3>\r\n   <p>For extra credit, anyone care to write the code I'd need to add to <tt>snippet<\/tt> to <b>disallow<\/b> inputs with an extra fields to work?  I gave a hint earlier in this column.\r\n   <\/p>\r\n   <p>Any thoughts on this topic?  If so, enter them <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=26\">here<\/a>.\r\n   <\/p>\r\n   <p class=\"footer\"><br>\r\n      Published with MATLAB&reg; 7.2<br><\/p>\r\n<\/div>\r\n<!--\r\n##### SOURCE BEGIN #####\r\n%% Fields of structs\r\n% MATLAB has some functions that are specifically designed for exploring\r\n% the contents of structures (entities known in MATLAB by the class\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/struct.html |struct|>).\r\n% I find the functions \r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/isfield.html |isfield|>\r\n% and\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/fieldnames.html |fieldnames|>\r\n% particularly helpful.  The reason I raise this area of functionality is\r\n% because some users new to MATLAB occasionally have trouble finding these\r\n% functions and try to use the function\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/exist.html |exist|>\r\n% to do the work for them and find it doesn't work out.\r\n%% Example Application\r\n% Suppose I'm writing an M-file to analyze data that I expect to come in a\r\n% |struct| with two fields, named |time| and |amplitude|.  Since I intend\r\n% to pass this M-file to lots of other folks, I want to write it somewhat\r\n% carefully so errors the users make give them enough information to\r\n% correct problems without having to consult me too often.\r\n\r\n%% snippet Help\r\n% Let's look at the help for our function first:\r\nhelp snippet\r\n\r\n%% Sample Data\r\n% Next let's get some data that is suitable for this function (|ss| and\r\n% |ssExtra|), and some that is not (|ssBad|).\r\n\r\nsunspots = load('sunspot.dat');\r\nss.time = sunspots(:,1);\r\nss.amplitude = sunspots(:,2);\r\nssBad.time = ss.time;\r\nssBad.amp = ss.amplitude;\r\nssExtra = ss;\r\nssExtra.other = datestr(today);\r\n\r\n%% Checking Inputs for Suitability with snippet with exist\r\n% Let's explore how I might check our different versions of the sunspot\r\n% data to see which one or ones is suitable for use with |snippet| so I\r\n% can figure out what code to put into |snippet| to do the error checking.\r\n% Remember, we want to check to see if the input is a |struct| and, if so,\r\n% that it has fields |time| and |amplitude|.\r\n% I'll begin by trying |exist|, and I am placing the code inside a\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/try.html try-catch>.\r\n% so I can capture any errors and easily show them.\r\ntry \r\n    exist(ss.time)\r\ncatch\r\n    err = lasterror;\r\n    disp(err.message)\r\nend\r\n\r\n%%\r\n% That didn't work because |exist| expects string input.  So here's my\r\n% next attempt.\r\ntry\r\n    exist('ss.time')\r\ncatch\r\n    err = lasterror;\r\n    disp(err.message)\r\nend\r\n\r\n%%\r\n% and that didn't work either!  What went wrong?  I gave |exist| a string\r\n% input.  Looking at the help carefully, I see that the name I give must be\r\n% a variable name or the name of some file or method.  So now let me check\r\n% my variable name using the function\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/isvarname.html |isvarname|>.\r\n\r\nisvarname('ss.time')\r\n%%\r\n% I can also see what variables I do have in my workspace:\r\nwhos\r\n%%\r\n% and I see that I have |ss| but not |ss.time| because |ss.time| is a\r\n% member of the |struct| but not a variable itself.  I've seen this\r\n% confusion between structures, their fields, and variables, fairly regularly on the \r\n% <http:\/\/.html MATLAB newsgroup>.\r\n%% Try struct-specific functions\r\n% I now understand that I have to look at the details of the structure\r\n% variables to see if the fields I need are there.  Here's the code I\r\n% wrote:\r\ntype snippet\r\n\r\n%% Try snippet on Incorrect Inputs\r\ntry\r\n    snippet(sunspots)\r\ncatch\r\n    err = lasterror;\r\n    disp(err.message)\r\nend\r\ntry\r\n    snippet(ssBad)\r\ncatch\r\n    err = lasterror;\r\n    disp(err.message)\r\nend\r\n%% Try snippet with Good Inputs\r\n% I leave it as an exercise for you to show that |snippet| runs correctly\r\n% using either |ss| or |ssExtra| as inputs.\r\n%% Extra Credit\r\n% For extra credit, anyone care to write the code I'd need to add to\r\n% |snippet| to *disallow* inputs with an extra fields to work?  I gave a\r\n% hint earlier in this column.\r\n\r\n%%\r\n% Any thoughts on this topic?  If so, enter them \r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=26 here>.\r\n##### SOURCE END #####\r\n-->","protected":false},"excerpt":{"rendered":"<p>\r\n\r\npre.codeinput {\r\n  background: #F9F7F3;\r\n  padding: 10px;\r\n  border: 1px solid rgb(200,200,200);\r\n}\r\n\r\n@media print {\r\n  pre.codeinput {word-wrap:break-word; width:100%;}\r\n} \r\n\r\nspan.keyword... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/03\/08\/working-with-structs\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/26"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=26"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/26\/revisions"}],"predecessor-version":[{"id":2614,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/26\/revisions\/2614"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=26"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=26"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=26"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}