A Best Friend, struct2table 13
Posted by Loren Shure,
Sometimes it's nice to have a best friend. Sometimes I have more than one, context-dependent. I want to share my best friend today for dealing with struct arrays.
Structure arrays are a useful way to collect similar information for a collection of items, even if what gets collected is not always the same size. However, struct arrays can also be cumbersome to work with. Thanks to the table datatype, I can now avoid some of the intricacies of indexing into struct arrays by simply performing a conversion to table first, and then using good, old-fashioned, stands the test of time, MATLAB indexing.
Contents
Some examples
Some examples for working with struct arrays after converting to a table include:
- output of dir - (I can then remove dirs, etc. very easily)
- jsondecode
- regionprops from Image Processing Toolbox - (now includes output to table option)
Let's try it
I'll now get the listing for the blog post directory for one of my guest authors, Alan Weiss.
dirstruct = dir('AlanW')
dirstruct = 5×1 struct array with fields: name folder date bytes isdir datenum
And here's a picture from the Windows Explorer
You can readily see that I really have only 3 items, and not the 5 suggested in dirstruct. I can, of course, now look at the names. I extract them via a comma-separated list.
dirstruct.name
ans = '.' ans = '..' ans = 'Clumping' ans = 'FinSymbolic' ans = 'Sudoku'
and now you can see that I really don't care about the first two. But I'd have to delete these from the name field, and the folder field, and ... So I definitely can do so, but what a hassle.
Instead let me convert to a table.
dirtable = struct2table(dirstruct)
dirtable = 5×6 table name folder date bytes isdir datenum _____________ ___________________________ ______________________ _____ _____ __________ '.' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05 '..' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05 'Clumping' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05 'FinSymbolic' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05 'Sudoku' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05
And now I can eliminate the first 2 rows in the usual way in MATLAB:
dirtable(1:2,:) = []
dirtable = 3×6 table name folder date bytes isdir datenum _____________ ___________________________ ______________________ _____ _____ __________ 'Clumping' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05 'FinSymbolic' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05 'Sudoku' 'C:\Work\ArtofMATLAB\AlanW' '22-Sep-2017 02:50:46' 0 true 7.3696e+05
Have you replaced your use of struct arrays with tables?
I'm wondering if you've used struct arrays before and are now replacing them with tables. And if you have an application where that does not make sense, I'd love to hear about that as well. Let me know here.
Get the MATLAB code
Published with MATLAB® R2017b
- Category:
- Data types,
- Structures
Note
Comments are closed.
13 CommentsOldest to Newest
dirstruct(1:2)=[];
Matt>I am not very successful in trying to start from an empty table and ‘grow’ it row by row.Yes, this is a little tricky. I had to get help on this myself from Mathworks support. The developers have indicated as well that this use-case needs better support. For now, a good way to accomplish this is like the following:
% How many rows in table? N = 3; %Initialize all table variables individually first VarA = NaN(N,l); VarB = cell(N,l); % Initialize table of desired size and types T = table(VarA,VarB); % Iterate through all table rows for row = 1 : N % Assign values to (i)'th table row T(row,:) = {rand,num2str(rand,2)}; end
You could of course have gotten rid of the unwanted directories by doing: dirstruct(1:2) = [];This if of course how buggy code is written. The assumption that '.' and '..' are always the first two entry is wrong. The ordering is alphabetical (as far as I know this is undocumented, so may not even always be true) and there are several characters that comes before '.', e.g. the '+' matlab package directories. A truly fullproof way of removing these directory
dirsctruct(ismember(dirstruct.name, {'.', '..'})) = [];What I don't understand is why matlab dir returns these completely pointless entries in the first place.
clear T for file = each(allFiles) in = readtable(file); if ~exist('T','variable') T = in; else T = [T; in]; end endThat's not nice but works ok. But tables are slower than structs, aren't they? Thanks!
T = table.empty; for file = each(allFiles) T = [T; readtable(file)]; end
Recent Comments