Struct to cell (or matrix) in Matlab
Solution 1
First make some example data:
n = 10;
ID = num2cell(randperm(n)');
Coordinate = mat2cell(randn(n, 3), ones(n,1));
Misc = num2cell(randn(n,1));
Conn = arrayfun(@randperm, randperm(n), 'UniformOutput', 0)';
Point = struct('ID', ID, 'Coordinate', Coordinate, 'Misc', Misc, 'Conn', Conn);
Now inspect it:
>> Point
Point =
10x1 struct array with fields:
ID
Coordinate
Misc
Conn
>> Point(1)
ans =
ID: 7
Coordinate: [-0.0571 -1.1645 2.4124]
Misc: 0.0524
Conn: [3 2 1]
Now use arrayfun()
to sweep through the elements of structure array Point
. We define a generic function x
to operate on each element of Point
, formatting the row like you described:
Point_cell = arrayfun(@(x) [num2cell([x.ID x.Coordinate x.Misc]) num2str(x.Conn)], Point, 'UniformOutput', 0);
Point_cell = vertcat(Point_cell{:})
Now inspect the output:
ans =
[ 7] [-0.0571] [-1.1645] [ 2.4124] [ 0.0524] '3 2 1'
[ 5] [ 0.2918] [ 0.4948] [ 0.7402] [-1.9539] '1 2'
[ 3] [-0.6146] [-1.2158] [ 0.3097] [ 0.5654] '3 4 1 2'
[10] [-0.0136] [ 1.5908] [-0.5420] [ 0.0778] [1x25 char]
[ 2] [ 0.4121] [ 0.5265] [ 0.1223] [ 0.0807] [1x22 char]
[ 1] [-0.9371] [ 0.2648] [ 0.9623] [ 0.7947] '1 2 5 4 3'
[ 4] [ 0.8352] [-0.3936] [-0.2540] [ 1.0437] '6 2 3 7 4 1 5'
[ 8] [ 1.0945] [-2.1763] [ 1.8918] [ 0.8022] '1'
[ 6] [ 0.3212] [-1.1957] [-1.2203] [-0.4688] [1x37 char]
[ 9] [ 0.0151] [ 0.3653] [-0.3762] [-0.0466] '3 5 4 2 6 1'
Couldn't tell from your question, but if you want all the numeric fields as an array inside a single cell, that is an easy tweak to do. Good luck!
Solution 2
Here is a slightly different solution using STRUCT2CELL:
%# build a sample array of structures
id = num2cell((1:10)',2); %'
coords = num2cell(rand(10,3),2);
misc = num2cell(rand(10,1),2);
conn = arrayfun(@(n)randi(5,[1 n]), randi([0 6],[10 1]), 'UniformOutput',false);
p = struct('ID',id, 'Coordinate',coords, 'Misc',misc, 'Conn',conn);
%# convert to cell array
h = fieldnames(p)'; %'
X = struct2cell(p)'; %'
%# split 'coords' field into 3 separate columns
h2 = {'xPos' 'yPos' 'zPos'};
X2 = num2cell( cell2mat(X(:,2)) );
%# convert 'conn' field to string
X4 = cellfun(@num2str, X(:,4), 'UniformOutput',false);
X4 = regexprep(X4, '[ ]+', ' '); %# clean multiple spaces as one
%# build final cell array with headers
C = [h(1) h2 h(3:4) ; X(:,1) X2 X(:,3) X4]
The result:
>> C
C =
'ID' 'xPos' 'yPos' 'zPos' 'Misc' 'Conn'
[ 1] [0.78556] [ 0.46707] [0.66281] [ 0.46484] '3'
[ 2] [0.51338] [ 0.6482] [0.33083] [ 0.76396] '2 1 2 5 1 2'
[ 3] [ 0.1776] [0.025228] [0.89849] [ 0.8182] '1 3 1 5'
[ 4] [0.39859] [ 0.84221] [0.11816] [ 0.10022] '1 1 2'
[ 5] [0.13393] [ 0.55903] [0.98842] [ 0.17812] '3 1 5 2 2 1'
[ 6] [0.03089] [ 0.8541] [0.53998] [ 0.35963] ''
[ 7] [0.93914] [ 0.34788] [0.70692] [0.056705] '2 1 3 4 4'
[ 8] [0.30131] [ 0.44603] [0.99949] [ 0.52189] '1 1 4 5 3'
[ 9] [0.29553] [0.054239] [0.28785] [ 0.33585] '1 5 2'
[10] [0.33294] [ 0.17711] [0.41452] [ 0.17567] '2'
where for example the second structure was:
>> p(2)
ans =
ID: 2
Coordinate: [0.51338 0.6482 0.33083]
Misc: 0.76396
Conn: [2 1 2 5 1 2]
user1007692
Updated on July 30, 2022Comments
-
user1007692 almost 2 years
I have a structure with fields
ID
,Coor
,Misc
,Conn
.ID
andMisc
are doubles, however,Coor
is a 1x3 vector andConn
is a 1xn vector (where n can theoretically be from 0 to inf).Point(x).ID = [x] Point(x).Coordinate = [xPos yPos zPos] Point(x).Misc = [randomDouble] Point(x).Conn = [someVectorOfNumbers]
I would like to have this mapped on a cell array, without using a FOR loop.
An example of the output:
'ID xPos yPos zPos Misc Conn' 1 0 0 0 0 '0 1 2' 2 1 1 1 1 '' ... x x x x x '2'
Notice that
Point.Conn
, its vector of numbers gets converted into a string.The issues that I am having is breaking up
Point.Coordinate
into its three elements, and convertingPoint.Conn
into a string.I feel like this can be done using struct2Cell and then changing the nesting level. I'm just not exactly sure how to do that.