How to assign a struct array to a field of another struct array?

63 次查看(过去 30 天)
Hello everybody, thanks in advance for your help with this!
So I'm trying to assign a struct array to a field of another struct array when both have the same size and obviously trying to avoid a for loop.
It looks something like this
data % This is a struct array that doesnt have the field trait yet
trait % this is a struct array of the same length of data
assert(length(data) == length(trait))
data.t = trait % this fails with --> Scalar structure required for this assignment.
[data.t] = [trait] % this fails with --> Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
[data.t] = [trait] % this fails with --> Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
[data.t] = deal(trait) % works but assigns the whole trait struct array to the field t in each element of data
Im pretty sure that if trait was a cell where each element of the cell was each of the elements in the struct array then this should work
[data.t] = cellTrain{:}
But I cant figure out a way to expand the trait struct-array into a cell as struct2cell expands every field in every struct of the struct array into cells.
Finally for completion the result should be equivalent to this simple for loop but hopefully a bit more efficient
for i = 1:length(data)
data(i).t = trait(i);
end
Thanks once again for all the help!
  2 个评论
Juan Sierra
Juan Sierra 2019-2-22
Heres a small script that you can run if you want to try ;)
load('testData.mat')
idx = sum(datenum([uniqueTrait.date])' < datenum([data.date]), 1);
trait = uniqueTrait(idx);
% data.t = trait; % this fails with --> Scalar structure required for this assignment.
% [data.t] = [trait]; % this fails with --> Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
% [data.t] = [trait]; % this fails with --> Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
% [data.t] = deal(trait); % works but assigns the whole trait struct array to the field t in each element of data
%% the result of this for loop should be the end result!
for i = 1:length(data)
data(i).t = trait(i);
end
It seems like a very simple thing to be honest but I cant figure out a way to avoid that loop XD

请先登录,再进行评论。

采纳的回答

Stephen23
Stephen23 2019-2-22
编辑:Stephen23 2019-2-22
You just need to use a comma-separated list
on the both sides of the allocation. MATLAB supports two ways to generate a comma-separated list from one array:
  1. from a cell array, or
  2. from the field of a structure (we can use this on the LHS)
and usually the first one is simpler to use, so this is what we will use on the RHS. Note that the fact that your array is also a structure is totally irrrelevant: the same methods can to be applied regardless of what class of array you want to allocate.
>> data = struct('A',{1,2,3},'B',{4,5,6})
1x3 struct array containing the fields:
A
B
>> trait = struct('Z',{7,8,9})
trait =
1x3 struct array containing the fields:
Z
>> C = num2cell(trait); % convert your array to a cell array of scalars.
>> [data.t] = C{:} % use a comma-separated list.
data =
1x3 struct array containing the fields:
A
B
t
>> data(3).t.Z
ans = 9
  2 个评论
Juan Sierra
Juan Sierra 2019-2-22
Ohhhh my!!!
Thanks so much! this was very helpful!
Honestly I thought num2cell was for numeric arrays only! It states on the documentation that it is to convert numeric arrays but if I apply isnumeric to trait it returns 0.
Well it works :)
Thanks again!
Stephen23
Stephen23 2019-2-22
编辑:Stephen23 2019-2-22
" It states on the documentation that it is to convert numeric arrays..."
The MATLAB documentation is surprisingly (how can I put this politely) ... flexible with its terminology. Most likely this is for historic reasons, from when MATLAB really did only support numeric and character array classes. In the last few years the input/output definitions have gained lists of allowed classes, but inside the text itself terms like "must be a matrix" are still used without further clarification (is my structure matrix a matrix? Is my graphics handle matrix a matrix? etc.).
Anyway, when you scroll down to the input definition, it lists these accepted classes:
Data Types: double | single | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | logical | char | string | struct | cell | categorical | datetime | duration | calendarDuration | function_handle

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Entering Commands 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by