Iterate over struct with length>1, with multiple fields
51 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
A Heidebrecht
am 16 Jul. 2024 um 17:50
Bearbeitet: Voss
vor etwa 4 Stunden
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 Kommentare
Stephen23
am 16 Jul. 2024 um 19:17
Bearbeitet: Stephen23
am 16 Jul. 2024 um 20:16
"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
Akzeptierte Antwort
Voss
am 16 Jul. 2024 um 18:00
Bearbeitet: Voss
am 16 Jul. 2024 um 18:06
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 Kommentare
Voss
vor etwa 4 Stunden
Bearbeitet: Voss
vor etwa 4 Stunden
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.
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Structures finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!