In a struct, how can you extract values for a vector of fieldnames

358 visualizzazioni (ultimi 30 giorni)
Hello,
I have a struct called MyStruct. I can extract the field names with the command
MyFieldNames = fieldnames(MyStruct);
If I'm interested in extracting the values for first n of MyFieldNames, is there a way I can do this using the "getfield" command? If I try
Temp = getfield(StateSpace, MyFieldNames(1:n))
or
Temp = Temp = getfield(StateSpace, MyFieldNames)
I get an error saying, "Index exceeds matrix dimensions."
Thank you, Kevin
  3 Commenti
Kevin Bachovchin
Kevin Bachovchin il 22 Feb 2013
For example, if MyStruct has 10 fields, and I was only interested in the first 3 of fields. MyFieldNames(1:3) would produce the field names associated with the first 3 fields. Is there a way to extract the values for the first 3 fields?
Kevin Bachovchin
Kevin Bachovchin il 22 Feb 2013
If it wasn't clear what I was asking, for example, assume 'x1' is one of the field names.
The command getfield(StateSpace,'x1') works fine and produces the desired result, but if I want to return values for multiple field names, is there a way to do this? Or do I have to extract the values one at a time using a for loop?

Accedi per commentare.

Risposta accettata

Kevin Bachovchin
Kevin Bachovchin il 22 Feb 2013
MyFieldNames = fieldnames(MyStruct);
for i=1:3
MyValues(i,1) = getfield(MyStruct,MyFieldNames{i});
end

Più risposte (4)

Michael Kane
Michael Kane il 16 Apr 2019
Kevin's answer can be condensed to oneline of code using cellfun
cellfun(@(x)(MyStruct.(x)),fieldnames(MyStruct))
You could even make this into an anonymous function fieldvalues
fieldvalues = @(MyStruct)(cellfun(@(fieldName)(MyStruct.(fieldName)),fieldnames(MyStruct)))

Azzi Abdelmalek
Azzi Abdelmalek il 22 Feb 2013
Modificato: Azzi Abdelmalek il 22 Feb 2013
Edit
if a is your struct array
s=fieldnames(a)
out=a
rmfield(out,s(4:end)) % will remove fields from 4 to the end
  11 Commenti
Kevin Bachovchin
Kevin Bachovchin il 22 Feb 2013
For your structure, I don't get an error, but for the structure I'm using, I do. Maybe it's because for my structure the values of the fields are 1x1 syms.

Accedi per commentare.


Jan
Jan il 22 Feb 2013
You could use a dedicated function like:
function Value = GetFields(S, Name)
if ischar(Name)
try
Value = S.(Name);
catch
Value = []; % Or an error message
end
elseif iscellstr(Name)
Value = cell(size(Name));
for iName = 1:numel(Name)
try
Value{iName} = S.(Name{iName});
catch
% Nothing or an error message?!
end
end
else
error('Input type not handled')
end
For large numbers of fieldnames is this more efficient:
function Value = GetFields(S, Name)
[dummy, iName, iS] = intersect(Name, fieldnames(S));
Value = cell(size(Name));
Data = struct2cell(S);
Value(iName) = Data(iS);
  1 Commento
Kevin Bachovchin
Kevin Bachovchin il 22 Feb 2013
It's much easier to just use a for loop. It's weird that MATLAB only allows the getfield command to take a single field as an argument, but that problem can be overcome by using a for loop.

Accedi per commentare.


Bart McCoy
Bart McCoy il 2 Lug 2021
There's just such an assymetry here. You have this great little function fieldnames() that accepts a struct and returns a cell array of names Where's the complementary fieldvalues() that accepts a struct and returns all struct values?
struct2cell() works great, but this question has been asked over & over for many years
Guess I'm writing my own.... just because: :)
function values = fieldvalues(struc)
% values = fieldvalues(struc)
%
% DESCRIPTION:
% Extracts all values from a struct and returns them as a Kx1 cell array,
% mirroring the functionality of MATLAB's fieldnames(struc)
%
%
% SEE ALSO:
% fieldnames(struc) Complementary function to fieldvalues
assert( isstruct(struc), sprintf("\n\nfieldvalues(struc)\n\tArgument 'struc' must be a structure\n\n"));
values = struct2cell(struc);
end

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!

Translated by