动态检查层次结构

时间:2015-07-13 14:20:28

标签: matlab data-structures

作为previous question关于如何字段分配给具有动态层次结构的结构变量的后续行动,我现在希望能够查询那些isfield的字段。但是,isfield只会使用一个参数,而不是setfield的列表。

总结我的问题: 我有一个将数据组织成结构变量的函数。根据某些标志,数据将保存到具有不同级别数的子结构中。

例如,我之前提出的问题的答案是我这样做来构建我的结构:

foo = struct();

% Pick one...
true_false_statement = true;
% true_false_statement = false;

if true_false_statement
    extra_level = {};
else
    extra_level = {'baz'};
end

foo = setfield(foo, extra_level{:}, 'bar1', 1);

如果foo.bar1 = 1true_false_statement,则为true,否则为foo.baz.bar1 = 1

现在我想测试字段的存在(例如预先分配一个数组)。如果我这样做:

if ~isfield(foo, extra_levels{:}, 'bar1')
    foo = setfield(foo, extra_level{:}, 'bar1', zeros(1,100));
end

我收到错误,因为isfield只会接受两个参数。

我能想到的最好的方法是用try ... catch块写一个单独的函数。

function tf = isfield_dyn(structure_variable, intervening_levels, field)
try
    getfield(structure_variable, intervening_levels{:}, field);
    tf = true;
catch err
    if strcmpi(err.identifier, 'MATLAB:nonExistentField')
        tf = false;
    else
        rethrow(err);
    end
end

正如评论中所提到的,这是一种hacky hack方法,它甚至不能很好地工作。

是否有更优雅的内置方式来执行此操作,或者其他一些更强大的方法来编写自定义函数来执行此操作?

2 个答案:

答案 0 :(得分:1)

您可能会发现getsubfield中的私有效用函数setsubfieldrmsubfieldissubfieldFieldTrip toolbox非常方便。来自getsubfield的文档:

% GETSUBFIELD returns a field from a structure just like the standard
% GETFIELD function, except that you can also specify nested fields
% using a '.' in the fieldname. The nesting can be arbitrary deep.
%
% Use as
%   f = getsubfield(s, 'fieldname')
% or as
%   f = getsubfield(s, 'fieldname.subfieldname')
%
% See also GETFIELD, ISSUBFIELD, SETSUBFIELD

答案 1 :(得分:-1)

我有点困惑,因为

isfield(foo,  'bar1')
isfield(foo,  'baz') 

似乎在你的示例结构上工作得很好。

当然,如果你想测试更多字段,只需在这些字段名上写一个循环并逐个测试它们。这可能看起来不是矢量化的,但肯定比滥用try-catch块来指导您的流程更好。

相关问题