作为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 = 1
为true_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方法,它甚至不能很好地工作。
是否有更优雅的内置方式来执行此操作,或者其他一些更强大的方法来编写自定义函数来执行此操作?
答案 0 :(得分:1)
您可能会发现getsubfield
中的私有效用函数setsubfield
,rmsubfield
,issubfield
和FieldTrip 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
块来指导您的流程更好。