필터 지우기
필터 지우기

Concatenate fields of a structure

조회 수: 11 (최근 30일)
Ferdi
Ferdi 2022년 4월 14일
댓글: Ferdi 2022년 4월 15일
Hi,
I have a structure inside an app:
app.C1 struct with fields:
DHO: {{1×3 cell} {1×3 cell}}
DHOnw: {{1×3 cell} {1×3 cell}}
with:
app.C1.DHO{1}= {["ID1"]} {["GD1"]} {["ED1"]}
app.C1.DHO{2}= {["ID2"]} {["GD2"]} {["ED2"]}
and
app.C1.DHOnw{1}= {["IDnw1"]} {["GDnw1"]} {["EDnw1"]}
app.C1.DHOnw{2}= {["IDnw2"]} {["GDnw2"]} {["EDnw2"]}
The fieldnames DHO, DHOnw are not fixed, and in other cases I could have different ones.
I want to create a new “quantity” with all these fields concatenated, for example:
new={ ‘ID1’; ‘GD1’; ED1; ‘ID2’; ‘GD2’; ED2; ‘IDnw1’; ‘GDnw1’; EDnw1; ‘IDnw2’; ‘GDnw2’; EDnw2;};
to be then used as a single column of a table.
I tried with cellfun, but I was not able to get reasonable results: do you have some suggestions?
Thank you in advance for your help.

채택된 답변

Stephen23
Stephen23 2022년 4월 14일
Note that using a string array is much more efficient than storing scalar strings in a cell array.
app.C1.DHO = {{"ID1","GD1","ED1"},{"ID2","GD2","ED2"}};
app.C1.DHOnw = {{"IDnw1","GDnw1","EDnw1"},{"IDnw2","GDnw2","EDnw2"}};
app.C1
ans = struct with fields:
DHO: {{1×3 cell} {1×3 cell}} DHOnw: {{1×3 cell} {1×3 cell}}
tmp = struct2cell(app.C1);
tmp = vertcat(tmp{:}).';
out = horzcat(tmp{:})
out = 1×12 cell array
{["ID1"]} {["GD1"]} {["ED1"]} {["ID2"]} {["GD2"]} {["ED2"]} {["IDnw1"]} {["GDnw1"]} {["EDnw1"]} {["IDnw2"]} {["GDnw2"]} {["EDnw2"]}

추가 답변 (3개)

Ferdi
Ferdi 2022년 4월 14일
Thank you very much!
I will try to follow your suggestion and using a string array.

Ferdi
Ferdi 2022년 4월 15일
Hi, I tried to follow your suggestion, surely not in the smartest way.
I recover the various function (DHO and so on) in this way (I keep the coding simple here):
function DHOSpinnerValueChanging(app, event)
app.nDHO = event.Value; % numers of DHOs
if app.nDHO ~= 0
app.PD = zeros(3*app.nDHO,1);
par0=[1,0.5,2]; %initialize some parameters
for ii=1:app.nDHO
app.PD(3*ii-2:3*ii)=ii*par0;
app.C1.DHO{ii}={"ID"+ii, "GD"+ii, "ED"+ii}; % scalar strings
app.T1.DHO(ii,:)=["ID"+ii "GD"+ii "ED"+ii]; % alternative: string array
end
end
and similarly for DHOnw.
You showed me how to treat app.C1.
To obtain a similar results witht he string array, I wrote a multiple loop:
A=string([]);
cf = cellfun(@(x) app.T1.(x), F, 'UniformOutput', false);
for j=1:numel(fieldnames(app.T1))
for k=1:height(cf{j})
for l=1:width(cf{j})
A=[A, cf{j}(k,l)];
end
end
end
A =
1×10 string array
"IL1" "GL1" "IL2" "GL2" "ID1" "GD1" "ED1" "ID2" "GD2" "ED2"

Ferdi
Ferdi 2022년 4월 15일
Hi again, I have a comment about your first answer.
It is working only when the fields have the same dimensions.
In case like:
app.C1 struct with fields:
Lrz: {{1×2 cell}}
DHO: {{1×3 cell} {1×3 cell}}
vertcat is not working anymore.
Is there a way to make it working in this more general case?
thanks!
  댓글 수: 2
Stephen23
Stephen23 2022년 4월 15일
"Is there a way to make it working in this more general case?"
Probably, once you specify the order that should be used for said "general case". The only reason I used VERTCAT was to provide the same order that you specified in your question. If the order is not significant, then you could use HORZCAT instead:
app.C1.Lrz = {{"One","Two"}};
app.C1.DHOnw = {{"IDnw1","GDnw1","EDnw1"},{"IDnw2","GDnw2","EDnw2"}};
app.C1
ans = struct with fields:
Lrz: {{1×2 cell}} DHOnw: {{1×3 cell} {1×3 cell}}
tmp = struct2cell(app.C1);
tmp = horzcat(tmp{:});
out = horzcat(tmp{:})
out = 1×8 cell array
{["One"]} {["Two"]} {["IDnw1"]} {["GDnw1"]} {["EDnw1"]} {["IDnw2"]} {["GDnw2"]} {["EDnw2"]}
Ferdi
Ferdi 2022년 4월 15일
thanks again, I should have found by myself.... sorry.
For general case I meant a variable number of functions.
I do not understand your reference to the order as it seems however preserved.
thanks

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

카테고리

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

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by