Iterate over struct with length>1, with multiple fields
10 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I have a struct with size>1, and multiple 16 fields.
Each fieldname corresponds to some quantity or property, and the struct stores these properties for 47 different items.
I'm trying to iterate the whole dataset. Preferrably, I'd like to iterate by fieldname and retrieve an array for each filename because within each field name the variable type is uniform.
To illustrate:
K>> teststruct = struct('name', ['Alice', 'Bob', 'Eve'], 'age', {24, 45, 35})
teststruct =
1×3 struct array with fields:
name
age
This shows up nicely as a table in the worspace browser.
However, if I iterate by fieldname, this goes wrong (spurious empty lines removed for readability):
K>> fnames = fieldnames(teststruct);
K>> teststruct.(fnames{1})
ans =
'AliceBobEve'
ans =
'AliceBobEve'
ans =
'AliceBobEve'
What I wanted was an array of all the names, instead I get three answers, of compounded names.
If I do the same with the 'age' field, at least each answer contains only one age, but they're still not in any kind of structure I could use in a code which does not know the size or field names of a struct it needs to deal with. In fact, if I assign the above to a variable, this happens:
K>> names = teststruct.(fnames{1})
names =
'AliceBobEve'
Doing the same with the other field only gives me the first age. One correct piece of data at least, but still not at all what I wanted...
I tried applying the code I found here, which promises to print the contents of an entire struct, but the same happens: I only get the first value of everything.
I know that I could loop over the struct indices first, and access them like this:
value = testsruct(i).(fieldnames(j))
...but then I'd be getting them separately, one by one, instead of getting back the cell array (or any other kind of array) that was used to define the struct in the first place, which is way easier to deal with.
Is that possible somehow?
3 Commenti
Stephen23
il 16 Lug 2024
Modificato: Stephen23
il 16 Lug 2024
"Is that possible somehow?"
Of course. Read this if you want to understand comma-separated lists and how to use them:
Also note that square brackets are a concatenation operator (not a "list" operator as some beginners incorrectly think, MATLAB does not have a "list" type). As Voss correctly pointed out, when you concatenate character vectors together you get one character vector:
['Alice', 'Bob', 'Eve']
You probably want a cell array:
{'Alice', 'Bob', 'Eve'}
For example:
S = struct('name', {'Alice', 'Bob', 'Eve'}, 'age', {24, 45, 35})
C = {S.name} % comma-separated list
Risposta accettata
Voss
il 16 Lug 2024
Modificato: Voss
il 16 Lug 2024
teststruct = struct('name', {'Alice', 'Bob', 'Eve'}, 'age', {24, 45, 35})
names = {teststruct.name}
ages = [teststruct.age]
Or, without hard-coding the field name references:
fnames = fieldnames(teststruct);
for ii = 1:numel(fnames)
values = {teststruct.(fnames{ii})};
disp(sprintf('field #%d (%s):',ii,fnames{ii}));
disp(values);
end
In this case each set of field values is stored in a cell array (previously the numeric ages were put into a numeric array) since a cell array can contain any class of variable.
6 Commenti
Voss
il 22 Lug 2024
Modificato: Voss
il 22 Lug 2024
You're welcome!
By the way, isnumeric(S.x) will throw an error about too many input arguments if S has more than one element (or an error about not enough input arguments if S is empty), because S.x is a comma-separated list (which is used as a set of input arguments to isnumeric in this case).
A way to check whether all values of a given field in a structure array are numeric is:
all(cellfun(@isnumeric,{S.x}))
which works regardless of what each x is in S, because they are put in a cell array ({S.x}), then cellfun iterates over the cells, running isnumeric on each cell's contents, getting true or false for each and concatenating those logicals into a single vector, which is passed to all.
Più risposte (0)
Vedere anche
Categorie
Scopri di più su Structures in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!