动态检查是否存在具有层次结构的结构字段名称 [英] Dynamically check for existence of structure field name with hierarchy

查看:176
本文介绍了动态检查是否存在具有层次结构的结构字段名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为对我的上一个问题的跟进要将分配给具有动态层次结构的结构变量,我现在希望能够使用 isfield 查询这些字段c>。但是, isfield 只会使用一个参数,而不是像 setfield 一样的列表。

As a follow-up to my previous question about how to assign fields to a structure variable with a dynamic hierarchy, I would now like to be able to query those fields with isfield. However, isfield will only take one argument, not a list as with setfield.

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

To summarize my problem: I have a function that organizes data into a structure variable. Depending on certain flags, the data is saved into the substructures with a different number of levels.

例如,我以前的问题的接受的答案是我这样做来构建我的结构:

For instance, the accepted answer to my previous question has me doing this to build my structure:

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 否则

which gives me foo.bar1 = 1 if true_false_statement is true, and foo.baz.bar1 = 1 otherwise.

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

Now I want to test for the existence of the field (for instance to pre-allocate an array). If I do this:

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

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

I get an error because isfield will only accept two arguments.

我能够想出的最好的办法是写一个单独的函数,一个 try ... catch block。

The best I've been able to come up with is to write a separate function with a try...catch block.

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

如下所述,这是一个黑客hack这样做的方式,甚至没有一切都很好。

As mentioned below in the comments, this is a hacky hack way to do this, and it doesn't even work all that well.

是否有更优雅的内置方式来做到这一点,还是其他更强大的写一个自定义函数的方式来做这个?

Is there a more elegant built-in way to do this, or some other more robust way to write a custom function to do this?

推荐答案

你可能会发现私有实用程序函数 getsubfield setsubfield rmsubfield 和< a href =https://github.com/fieldtrip/fieldtrip/blob/master/private/issubfield.m =nofollow> issubfield FieldTrip工具箱非常方便从 getsubfield 的文档:

You might find the private utility functions getsubfield, setsubfield, rmsubfield, and issubfield from the FieldTrip toolbox very handy. From the documentation of 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

这篇关于动态检查是否存在具有层次结构的结构字段名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆