Question

I have data as a struct with several layers, for example:
data.A.B
The data I want to access is in layer B. But the problem is that field names in B can be different depending on where the data comes from. Therefore I can't just type:
data.A.B.myData
myData is itself a struct

I can use:
fieldnames(data.A)
to find the names, but this doesn't help my much. I would have to write code sections for every possible field name that can occur at this level. And that's just what i trying to avoid.

Is there a way to get down to the data I have (myData) without knowing the field names of B?

Was it helpful?

Solution

Traditionally, you can loop over the fieldnames and perform the search of myData at a specific sub-structure of the struct. However, if you don't know which sub-structure you need to search, then you can perform a recursive algorithm. Below is an example. It will return the first match of myData in the struct or an empty matrix if no match found. The code can be improved to find all matches of myData.

function S2=getmyfield(S1,queriedField)

if isstruct(S1)
    % Get all fieldnames of S1
    fieldArray=fieldnames(S1);

    % Find any match with the queried field. You can also use isfield().
    % If there is a match return the value of S1.(queriedField),
    % else perform a loop and recurse this function.
    matchTF=strcmp(queriedField,fieldArray);
    if any(matchTF)
        S2=S1.(fieldArray{matchTF});
        return;
    else
        S2=[];
        i=0; % an iterator count
        while isempty(S2)
            i=i+1;
            S2=getmyfield(S1.(fieldArray{i}),queriedField);
        end
    end
else
    S2=[];
end

end

Cheers.

OTHER TIPS

You just need a recursive function that checks fieldnames at each level for the structure. This is roughly what you need (it could be improved to supply the path to the found field).

function [ value, found ] = FindField( rootStruct, fieldName )
%FindField - Find a field with a structure
    value = [];
    found = 0;
    if isstruct( rootStruct )
        fields = fieldnames(rootStruct);
        for fi=1:length(fields)
            if strcmp(fields{fi}, fieldName )
                value = rootStruct.(fieldName);
                found = true;
                return;
            end
            [value, found ] = FindField( rootStruct.(fields{fi}), fieldName );
            if found
                return;
            end
        end
    end

end

Usage example:

a.b = 1;
a.b.c = 2;
a.b.d = struct('Index',1,'Special',2);
FindField(a,'d')


ans = 

      Index: 1
    Special: 2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top