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

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

What do you mean by the first field?
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?
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?

댓글을 달려면 로그인하십시오.

 채택된 답변

Kevin Bachovchin
Kevin Bachovchin 2013년 2월 22일

2 개 추천

MyFieldNames = fieldnames(MyStruct);
for i=1:3
MyValues(i,1) = getfield(MyStruct,MyFieldNames{i});
end

추가 답변 (4개)

Michael Kane
Michael Kane 2019년 4월 16일
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)))
Jan
Jan 2013년 2월 22일
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

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.

댓글을 달려면 로그인하십시오.

Azzi Abdelmalek
Azzi Abdelmalek 2013년 2월 22일
편집: Azzi Abdelmalek 2013년 2월 22일
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

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?
Azzi Abdelmalek
Azzi Abdelmalek 2013년 2월 22일
편집: Azzi Abdelmalek 2013년 2월 22일
Look at edited answer
I'd prefer to get a 1x3 matrix for values in fields 1 to 3. Is there a way to do that all at once rather than extracting the values one at a time in a for loop like shown below?
MyFieldNames = fieldnames(MyStruct);
for i=1:3
MyValues(i,1) = getfield(MyStruct,MyFieldNames{i});
end
I am not following you. Have you tried the edited answer?
s=fieldnames(a)
out=a
rmfield(out,s(4:end)) % will remove fields from 4 to the end
Once you get your three fields in the variable out use
result=reshape(cell2mat(struct2cell(out)),3,[])
Yes, I did. Your code produces a 1x1 struct with 3 fields as the answer. I'm looking to obtain a 1x3 for the values only, which is what my code using the for loop does. If there's no simpler way of doing that besides the for loop, that's fine I guess. I just would have thought MATLAB would have some built-in way of extracting values for more than 1 field at a time.
s=fieldnames(a)
out=a
out=rmfield(out,s(4:end))
result=reshape(cell2mat(struct2cell(out)),3,[])
The last line produces an error for me. "Error using cell2mat (line 53) Cannot support cell arrays containing cell arrays or objects."
I think I'm just going to stick with extracting the values using the for loop unless there is some way to use the "getfield" command with multiple fields at a time.
Look at this example
out=struct('v',{4},'y',{6},'z',{45})
result=reshape(cell2mat(struct2cell(out)),3,[])
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.
result=struct2cell(out)

댓글을 달려면 로그인하십시오.

Bart McCoy
Bart McCoy 2021년 7월 2일
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

카테고리

도움말 센터File Exchange에서 Data Type Identification에 대해 자세히 알아보기

질문:

2013년 2월 22일

답변:

2021년 7월 2일

Community Treasure Hunt

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

Start Hunting!

Translated by