【问题标题】:MATLAB: Pass part of structure field name to functionMATLAB:将结构字段名称的一部分传递给函数
【发布时间】:2017-10-20 14:40:45
【问题描述】:

我需要将结构名称的一部分传递给函数。

可用结构示例:

systems.system1.stats.equityCurve.relative.exFee
systems.system1.stats.equityCurve.relative.inFee
systems.system2.stats.equityCurve.relative.exFee
systems.system2.stats.equityCurve.relative.inFee
systems.system1.returns.aggregated.exFee
systems.system1.returns.aggregated.inFee
systems.system2.returns.aggregated.exFee
systems.system2.returns.aggregated.inFee
... This goes on...

在一个函数中,我循环遍历结构如下:

function mat = test(fNames)

feeString = {'exFee', 'inFee'};
sysNames = {'system1', 'system2'};

for n = 1 : 2
    mat{n} = systems.(sysNames{n}).stats.equityCurve.relative.(feeString{n});
end

end

我喜欢在循环中灵活处理的是中间部分,即systems.(sysNames{n}) 之后和.(feeString{n}) 之前的部分(比较示例)。

我现在正在寻找一种将中间部分作为输入参数fNames 传递给函数的方法。循环应该包含类似

mat{n} = systems.(sysNames{n}).(fName).(feeString{n});

【问题讨论】:

  • 处理动态字段名称可能会很麻烦,特别是如果您没有固定数量的字段,所以我唯一的建议(虽然它很笨重)是使用类似的东西:eval([ 'mat{n} = systems.(sysNames{n}).',fNames,'.(feeString{n});'])
  • @DanielAldrich 请不要。这与理智的数据处理完全相反。 eval 速度慢且不安全,它使代码不可读。动态字段名称很好用,而且语义正确。请不要试图说服无辜的用户相反。我们正在努力处理matlab 标签,以使提问者远离eval 厄运之路。

标签: matlab function struct


【解决方案1】:

如何使用辅助函数,例如

function rec_stru = recSA(stru, field_names)
if numel(field_names) == 1
    rec_stru = stru.(field_names{1});
else
    rec_stru = recSA(stru.(field_names{1}), field_names(2:end));
end

此函数将中间字段名称作为元胞数组。 这将变成这样的陈述:

mat{n} = systems.(sysNames{n}).stats.equityCurve.relative.(feeString{n});

进入

mat{n} = recSA(systems.(sysNames{n}), {'stats', 'equityCurve', 'relative', feeString{n}});

然后可以将元胞数组的第一部分作为参数传递给函数。

【讨论】:

    【解决方案2】:

    这是 matlab 在文档中有点无用的情况之一。有一种方法可以使用 matlab 中的fieldnames 函数来获取所有字段的列表并使用动态字段对其进行迭代。

    systems.system1.stats.equityCurve.relative.exFee='T'
    systems.system1.stats.equityCurve.relative.inFee='E'
    systems.system2.stats.equityCurve.relative.exFee='S'
    systems.system2.stats.equityCurve.relative.inFee='T'
    systems.system1.returns.aggregated.exFee='D'
    systems.system1.returns.aggregated.inFee='A'
    systems.system2.returns.aggregated.exFee='T'
    systems.system2.returns.aggregated.inFee='A'
    
    
    dynamicvariable=fieldnames(systems.system1)
    

    这将返回可用于迭代的字段名称的单元矩阵。

    systems.system1.(dynamicvariable{1})
    
    ans = 
    
    equityCurve: [1x1 struct]
    

    理想情况下,您应该以这样一种方式固定您的数据结构,以便您知道数据结构中有多少层深度。

    【讨论】:

    • 但是 OP 似乎知道字段名称,他们只需要动态地(递归地)访问它们?
    • 我知道可能的字段名,但有一个例外:我不知道第二级的编号,即有 N 个系统(system1、system2、...、systemN)。有几个“中间部分”(已知)和两个末端部分(.exFee 和 .inFee)。
    • 可能在你的函数中使用 isstruct 来保持你的嵌套数据结构下降 1 级,直到你得到费用
    • @Andi 建议与@zeeMonkeez 发布的相同,使用isstruct 而不是numel(field_names) 编写一个辅助函数,这将在您到达嵌套的最后一层时保持更多的灵活性结构。
    猜你喜欢
    • 1970-01-01
    • 2014-07-13
    • 2015-08-27
    • 2021-10-10
    • 2012-05-09
    • 1970-01-01
    相关资源
    最近更新 更多