Concatenate fields of a structure

5 次查看(过去 30 天)
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 中查找有关 Cell Arrays 的更多信息

产品


版本

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by