## Loren on the Art of MATLABTurn ideas into MATLAB

### This is machine translation

Translated by
Mouseover text to see original. Click the button below to return to the English version of the page.

# A Best Friend, struct2table13

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:

1. output of dir - (I can then remove dirs, etc. very easily)
2. jsondecode
3. 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

### Note

Matt replied on : 1 of 13

You could of course have gotten rid of the unwanted directories by doing: dirstruct(1:2) = [];

I use tables more and more and find them useful. But I am not very successful in trying to start from an empty table and ‘grow’ it row by row. And in some cases I have reverted to using structures as it is awkward when you want the different rows of a column to have different sized arrays.

Peter Verheijen replied on : 2 of 13

Why couldn’t I use dirstruct(1:2)=[] and reach the same result? If my observation is right, one does not need ‘struct2table’. Is there any other application where ‘struct2table’ has an advantage?

Brad Stiritz replied on : 3 of 13

Hi Loren, yes struct2table() is a great conversion function. I recently made good use of it while leveraging a helpful Github repository I found, which is several years old. That code outputs a vector of structs. I convert that output first to table, and then to timetable for further processing. I will be posting my project to File Exchange before long.

In the reverse direction, I find that table2struct() is extremely helpful as well, for display / output of single rows in a table. The usefulness rises in direct proportion to the number of table variables (i.e. columns) ;)

Cris replied on : 4 of 13

I like tables a lot, and they’re more efficiently stored than structs as well. But this example is strange, because I can also do

dirstruct(1:2)=[];
Loren Shure replied on : 5 of 13

Sure to all of you, I can use the simple deletion syntax you’ve shown. However it’s harder if I want to search for multiple conditions in multiple columns to do the deletion from the struct arrays vs. the tables.

Brad Stiritz replied on : 6 of 13

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

Thom replied on : 7 of 13

I used to simply remove the first two entries from dir() until I encountered filenames that begin with ! – rare, but will break dirstruct(1:2)=[];

Converting to a table would allow for easy removal of . and .. by filtering by name rather than looping through the struct and removing entries. Avoiding the problem by filtering using dir(pattern) is better if possible, but being easily able to convert structs to tables is pretty handy elsewhere.

Lara Harris replied on : 8 of 13

Excellent function I hadn’t used before! One issue: applying when you have nested structures. I just tried using after jsondecode and ran into trouble as the struct contains structs contains structs (ever tried parsing the export from a Trello board?! jsondecode is a godsend, but you still need to go several levels deep to extract what you’re looking for). Would be perfect if struct2table converted any inner structs to separate tables, or ignored them, rather than throwing an error. Regardless, I’m sure I will be using this in future.

Julian Thorp replied on : 9 of 13

Funnily enough I used struct2table for the very same use case.

You blog post has inspired me to post my function (from ~2016) onto the File Exchange!

Guillaume de Sercey replied on : 10 of 13

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.

Jan Kappen replied on : 11 of 13

I love tables. They’ve almost replaced (data) structs everywhere for me because of the better visualization, filtering, indexing and so on. If I need structs for compatibility reasons, table2struct is great, especially the “ToScalar” parameter is great to switch between a an array of structs vs struct of arrays!
By the way, you can preallocate tables in R2018, see https://de.mathworks.com/help/matlab/release-notes.html.
What I usually do to grow tables is something like

clear T

for file = each(allFiles)
if ~exist('T','variable')
T = in;
else
T = [T; in];
end
end


That’s not nice but works ok.

But tables are slower than structs, aren’t they?

Thanks!

Andy Campbell replied on : 13 of 13

Jan,

How about this so you don’t need the if statement and the exist check?

T = table.empty;
for file = each(allFiles)
T = [T; readtable(file)];
end