# What is the possibly easiest way to convert back and forth between a struct scalar and a struct array?

2 views (last 30 days)
Bohan Liu on 5 May 2018
Edited: Stephen Cobeldick on 5 May 2018
Suppose there is a struct scalar, each field of which contains a numeric array of the same size. I would like to convert it into a struct array of the same size as the individual fields of the struct scalar, and convert it back to the original struct scalar. I wrote a short script on my own with some exemplary data, as follows:
PointScalar=struct('x',{magic(5)},'y',{ones(5)},'z',{eye(5)});
%struct scalar to struct array
PointArray=structfun(@num2cell,PointScalar,'UniformOutput',0);
PointArray=struct('x',PointArray.x,'y',PointArray.y,'z',PointArray.z);
%struct array back to struct scalar
for fld=fieldnames(PointArray)'
PointScalarNew.(fld{:})=reshape([PointArray(:).(fld{:})],size(PointArray));
end
But I think with a sufficiently large number of fields, this method would become infeasible, and also I would try to bypass the use of for-loop as much as I could. So I wonder if there are any better ways that achieve the same goal. Thanks a lot!

Stephen Cobeldick on 5 May 2018
Edited: Stephen Cobeldick on 5 May 2018
Use struct2cell, cell2struct, and fieldnames, like this:
% scalar data:
S = struct('x',magic(5),'y',ones(5),'z',eye(5));
% scalar -> non-scalar:
C = struct2cell(S);
C = num2cell(cat(3,C{:}));
A = cell2struct(C,fieldnames(S),3);
% non-scalar -> scalar:
C = permute(struct2cell(A),[2,3,1]);
C = num2cell(cell2mat(C),1:2);
Z = cell2struct(C,fieldnames(S),3);
And testing against the outputs from your original code:
>> isequal(A,PointArray)
ans =
1
>> isequal(Z,PointScalar)
ans =
1
>> isequal(Z,PointScalarNew)
ans =
1