Concatenate name fields in nested structure

Hello,
I am trying to save value of the data placed in the last fields in nested structure by concatenating string in recursion. The name of the file should string composed of the all preceding fields in structure.
However I am not able to save previous fields.
The code is as follows:
nameDataBase = 'database.mat';
structNest = load([pathFolder, nameDataBase]);
structFields = myIsField(structNest, 'data');
pathOutputFile = pathFolder;
fileName = ''
function isFieldResult = myIsField (inStruct, fieldName)
% inStruct is the name of the structure or an array of structures to search
% fieldName is the name of the field for which the function searches
B = struct();
display('output folder')
isFieldResult = 0;
f = fieldnames(inStruct(1))
f1 = string(fieldnames(inStruct(1)))
for i=1:1%length(f)
display("i")
i
if(strcmp(f{i},strtrim(fieldName)))
isFieldResult = 1;
display('data found - end')
B.(f{i}) = inStruct(1).(f{i})
data = getfield(B,'data')
return;
elseif isstruct(inStruct(1).(f{i}))
isFieldResult = myIsField(inStruct(1).(f{i}), fieldName);
B.(f{i}) = inStruct(1).(f{i})
if isFieldResult
display('time found -loop')
return;
end
end
end

1 件のコメント

Ganesh
Ganesh 2024 年 6 月 13 日
If you could upload the file 'database.mat' and describe what the output you would like to see is, it would be very helpful.

サインインしてコメントする。

 採用された回答

Voss
Voss 2024 年 6 月 13 日

1 投票

S = struct( ...
'A1',1, ...
'A2',struct('B1',2,'not_data',3,'data',4), ...
'A3',struct( ...
'B1',struct('not_data',5), ...
'B2',struct( ...
'C1',struct('data',6), ...
'data',struct( ...
'D1',struct('data',7)))))
S = struct with fields:
A1: 1 A2: [1x1 struct] A3: [1x1 struct]
S.A2
ans = struct with fields:
B1: 2 not_data: 3 data: 4
S.A3
ans = struct with fields:
B1: [1x1 struct] B2: [1x1 struct]
S.A3.B1
ans = struct with fields:
not_data: 5
S.A3.B2
ans = struct with fields:
C1: [1x1 struct] data: [1x1 struct]
S.A3.B2.C1
ans = struct with fields:
data: 6
S.A3.B2.data
ans = struct with fields:
D1: [1x1 struct]
S.A3.B2.data.D1
ans = struct with fields:
data: 7
function [out,data] = get_full_field_names(S,name,str)
out = strings(0);
data = cell(0);
if nargin < 3
str = "";
end
f = fieldnames(S);
for ii = 1:numel(f)
if isstruct(S.(f{ii}))
[new_out,new_data] = get_full_field_names(S.(f{ii}),name,str+f{ii}+".");
out = [out, new_out];
data = [data, new_data];
elseif strcmp(f{ii},name)
out = [out, str+name];
data = [data, {S.(f{ii})}];
end
end
end
[names,data] = get_full_field_names(S,'data')
names = 1x3 string array
"A2.data" "A3.B2.C1.data" "A3.B2.data.D1.data"
data = 1x3 cell array
{[4]} {[6]} {[7]}
[names,data] = get_full_field_names(S,'not_data')
names = 1x2 string array
"A2.not_data" "A3.B1.not_data"
data = 1x2 cell array
{[3]} {[5]}
[names,data] = get_full_field_names(S,'something_else')
names = 0x0 empty string array data = 0x0 empty cell array

5 件のコメント

Elzbieta
Elzbieta 2024 年 6 月 14 日
Voss, Thank you a lot. However each string composed of the structure fields should containing data at its end should be name of the separeted file. I do not join data fields with ech other. For instance:
S1.a1.time-> I do not create a separate file
S1.a1.data -> I create file S1_a1_data
S2.a1.time-> I do not create a separate file
S2.a1.data -> I create file S2_a1_data
Elzbieta
Elzbieta 2024 年 6 月 14 日
How to include only these structure fields having also specified field previously like a1?
Voss
Voss 2024 年 6 月 14 日
編集済み: Voss 2024 年 6 月 14 日
You're welcome!
"However each string composed of the structure fields should containing data at its end should be name of the separeted file."
I don't understand the objection. The code returns the "full path" through the nested structure of all terminal (non-structure) fields whose name is the requested name (e.g., 'data'). So if you do
get_full_field_names(S,'data')
it will return those locations corresponding to fields called 'data' (and not 'time' or anything else). It also returns the data (i.e., the value of each field 'data') corresponding to each of those locations. So you could create the files like:
[names,data] = get_full_field_names(S,'data');
for ii = 1:numel(names)
x = data{ii};
save(names(ii),'x'); % save variable x to mat file called names(ii)
end
If you want underscores instead of periods in the file names, replace "." with "_" here:
[new_out,new_data] = get_full_field_names(S.(f{ii}),name,str+f{ii}+"_");
% ^ here
If you want the name of the top-level structure (e.g., "S2") to be included in the file names, you can prepend it:
[names,data] = get_full_field_names(S2,'data');
names = "S2"+names;
"How to include only these structure fields having also specified field previously like a1?"
You can filter the results after the fact, as in:
[names,data] = get_full_field_names(S,'data');
idx = contains(names,"a1_"); % or "a1." if using period delimiter
names = names(idx);
data = data(idx);
Elzbieta
Elzbieta 2024 年 6 月 15 日
移動済み: Stephen23 2024 年 6 月 15 日
Thank you for your comments. Voss your solution works great!
Voss
Voss 2024 年 6 月 15 日
You're welcome and thank you!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

質問済み:

2024 年 6 月 13 日

コメント済み:

2024 年 6 月 15 日

Community Treasure Hunt

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

Start Hunting!

Translated by