필터 지우기
필터 지우기

Assign value to field of nested structure in a structure array

조회 수: 20 (최근 30일)
Hello, I will use a simple example to show what I am after. I have a structure array 'person' with fields ('First_Name' , 'Last_Name' , 'FamilyInfo'), where 'FamilyInfo' is a structure with three fields ('FatherName' , 'MotherName' , 'NumberOfSiblings').
I create 4 elements in person structure array and fill all the 'First_Name' and 'Last_Name' fields but the 'FamilyInfo' field is left empty. Now, for all the 4 elements in the 'person' structure array, I want to assign at once the same value to the field "NumberOfsiblings" in the nested structure 'Family', but MATLAB throws an error. Here is the code;
Create an empty structre array
person = struct('First_Name',[],'Last_Name',[],...
'FamilyInfo',struct('FatherName',[],'MotherName',[],'NumberOfsiblings',[]));
Create elements in the array but the Family field is left empty
FirstNames = {'Joe','Jack','William','Averel'};
[person(1:4).First_Name]=deal(FirstNames{:});
[person(1:4).Last_Name]=deal('Dalton');
For all the elements in person structure array, assign the same value (3) to the NumberOfsiblings field, of the Family field.
[person(1:4).FamilyInfo.NumerOfsiblings] = 3;
Error message pops up;
Expected one output from a curly brace or dot indexing expression, but there were 4 results.
Is there a way to do it without using a for loop? One-line code is preferred. Thanks
  댓글 수: 2
Pico Technology
Pico Technology 2016년 10월 17일
Is this the actual code run or should it be
[person(1:4).FamilyInfo.NumberOfsiblings] = 3;
Konstantinos Tompoulidis
Konstantinos Tompoulidis 2016년 10월 17일
I don't understand your question. What I wrote is the code I run but it pops an error. I don't know what the correct code is. I am still looking for it.

댓글을 달려면 로그인하십시오.

채택된 답변

Guillaume
Guillaume 2016년 10월 17일
That's one of the downside of multilevel structures. As Jan says, it's not possible to assign at once to fields of a substructure.
More importantly, note that when you grow the root source structure (by adding the first names of the 4 persons, only the 1st element of the structure array is a FamilyInfo substructure. The other 3 are initialised empty, because matlab does not copy the type of fields when it grows structure arrays. So if you actually want to have the correct FamilyInfo substructure after growing, you actually need to deal a FamilyInfo field to each element. You may as well set the value of NumberOfSiblings to the correct one:
[person.FamilyInfo] = deal(struct('FatherName',[],'MotherName',[],'NumberOfsiblings',3);
Note that if you want to avoid losing the FamilyInfo struct, don't grow the array but initialise it at the correct size to start with:
numpersons = 4;
person = struct('First_Name',[],'Last_Name',[],...
'FamilyInfo',repmat({struct('FatherName',[],'MotherName',[],'NumberOfsiblings',[])}, 1, numpersons));
  댓글 수: 2
Konstantinos Tompoulidis
Konstantinos Tompoulidis 2016년 10월 17일
편집: Konstantinos Tompoulidis 2016년 10월 17일
Could you explain a little bit the last line of code that you wrote, please?
Thanks!
Guillaume
Guillaume 2016년 10월 17일
I'm not sure what you want me to explain. If you pass a cell array for one the field values to struct, it creates a structure array by distributing the content of the cell array to each struct array element.
Therefore, here I'm just repmat'ing a scalar cell to the desired array size, so each structure is automatically initialised to the same value.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Jan
Jan 2016년 10월 17일
편집: Jan 2016년 10월 17일
This does not work "at once". Simply use a loop:
for k = 1:4
person(k).FamilyInfo.NumberOfsiblings = 3;
end
  댓글 수: 4
Jan
Jan 2016년 10월 19일
@Konstantinos: Discussing your wanting to avoid a loop takes more time than writing it. A loop is clean and efficient here, nice and compact.
broken_arrow
broken_arrow 2021년 9월 30일
편집: broken_arrow 2021년 9월 30일
I agree with @Konstantinos Tompoulidis that this syntax limitation is a nuisance, especially in OOP. After all, structs are constructed in such a way as to imitate the "physical nature" of the objects and one does not want to warp the structure just to comply with syntax limitations. Of course looping is possible, but according to the principle "vectorize where you can", it is not optimal. Reading and writing should also be possible with multiple outputs on multiple levels, like
[a(:).b.c(:).d] = deal(1)

댓글을 달려면 로그인하십시오.


Jos (10584)
Jos (10584) 2016년 10월 17일
[person(1:4).FamilyInfo] = deal(struct('NumerOfsiblings',3)) ;
  댓글 수: 1
Guillaume
Guillaume 2016년 10월 17일
That will actually remove the FatherName and MotherName subfields for any of the FamilyInfo fields that have them.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Structures에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by