Is it possible to create a nested structure with dynamic field names?

93 visualizaciones (últimos 30 días)
I am parsing an ascii data header file with obnoxiously human unreadable field names like:
structureName.manufacturer.modelNumber.serialNumber.hardwarePartID(6).hardwareAddresses(24).featureList(274).licensed = "1"
There are thousands of lines, and since this needs to be inspected by a human from time to time, I am reorganizing the information into a more readable and workable format, but I have run into a problem. I need only certain lines of data, and only if those lines exist. I have settled upon making a variable list of parameters I need (based on the specific application), and I have read the ascii text into structures with the same field names. The problem is when I have to assign these parsed parameter values into my new (readable) structure, I have to step through the list of field names.
I would like to be able to use dynamic field naming to make the assignments. For instance,
fieldname = 'charles'; %this name would change with every step, and itself will be nested as well
structureName.(fieldname) = parsedStructure.(manufacturer).(modelNumber). ... %etc
However, this version of dot indexing (right side dynamic naming) is not supported. Neither is:
structureName.(fieldname) = parsedStructure.(manufacturer.modelNumber) ... %etc
And, of course, the first thing I tried was using the dotted fieldnames as text:
parsedField = 'manufacturer.modelNumber.whateverNonsenseComesAfterThis';
structureName.(fieldname) = parsedStructure.(parsedField);
But using nested field names isn't supported either. Or at least, I haven't been able to figure out how to do it.
I can make it work with an eval call, but there are several reasons why that isn't a good idea, and I'd rather not stick with that solution. Basically, what I need to do is be able to step through a list of (hundreds of) required parameters, and for those that exist in the data, extract them into my new structure.
Any ideas?
  6 comentarios
Stephen23
Stephen23 el 27 de En. de 2023
Editada: Stephen23 el 27 de En. de 2023
"Is there a technique I have overlooked?"
As I wrote in my answer, you can use GETFIELD(), probably with a comma-separated list:
And on the LHS basic dynamic fieldname:
S.A.B.C = pi;
F = 'A.B.C';
C = split(F,'.');
Z.('new') = getfield(S,C{:})
Z = struct with fields:
new: 3.1416
Jeffrey Luci
Jeffrey Luci el 27 de En. de 2023
Editada: Jeffrey Luci el 27 de En. de 2023
I didn't overlook that. You can't get or set nested fieldnames with those functions.
f = 'one.two.three';
fSplit = split(f, '.');
hdr = setfield(hdr, fSplit, 1);
%This isn't supported, either:
hdr = setfield(hdr, f, 1);

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 20 de En. de 2023
Editada: Stephen23 el 20 de En. de 2023
"However, this version of dot indexing (right side dynamic naming) is not supported."
Lets try it right now:
S.A.B.C = pi;
S.('A').('B').('C')
ans = 3.1416
If you want to mix in subscript indexing as well then you can use GETFIELD() / SETFIELD():
S.A.B(2).C = exp(1);
getfield(S,{1},'A',{1},'B',{2},'C')
ans = 2.7183
Another option is to use SUBSREF() / SUBSASGN():
X = substruct('.','A', '.','B', '()',{2}, '.','C');
subsref(S,X)
ans = 2.7183
Obviously you just need to use STRSPLIT() or similar to get each level of the structure heirarchy from your single piece of text, and handle those subscript indices correctly. You might find cell arrays and comma-separated lists very useful:

Más respuestas (0)

Categorías

Más información sobre Logical en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by