从他的名字Matlab获取可变内容

时间:2018-03-28 15:39:12

标签: matlab struct

我想从名称中获取变量的内容为字符串:

 %suppose that I have structures variables  in the workspace:
    struct_1=struct('field1' ,"str",'field2',0:5)
    struct_2=struct('field1' ,"str",'field2',0:10)
    struct_3=struct('field1' ,"str",'field2',0:20)
    %and I have an other  variable like:
    a=5
    var2='hello'
    %and I want to concatenate all these structures in the same structure
    %So i wan to get their name.
    %I don't know if there is an other way to get just the structure variables
    structures=who(str*)
    array=[]
    for i=1:length(structures)
        array=[array; structures(i). field2]; % here I get an error because the content of structures are string representing the variable name
    end
%create the new struct
  str='newstr_value'
  struct_4=struct('field1',str, 'field2',array)

如何修复此错误,有没有办法更好地做到这一点?

2 个答案:

答案 0 :(得分:1)

虽然我仍然高度建议回到这些动态命名结构的起源点(如果这实际上是输出,那么工具箱创建者会感到羞耻......)并在那里解决这个问题,有一种方法不需要使用eval

my approach类似的切向相关问题,您可以save将所需结构添加到临时*.mat文件中,并利用load的可选结构输出在更强大的计划事项中整合数据结构以便访问。

例如:

struct_1=struct('field1' ,"str",'field2',0:5);
struct_2=struct('field1' ,"str",'field2',0:10);
struct_3=struct('field1' ,"str",'field2',0:20);

save('tmp.mat', '-regexp', '^struct_');
clear

oldworkspace = load('tmp.mat');
varnames = fieldnames(oldworkspace);
nvars = numel(varnames);

% Get original structure fields
% The subsequent steps assume that all input structs have the same fields
fields = fieldnames(oldworkspace.(varnames{1}));
nfields = numel(fields);

% Initialize output struct
for ii = 1:nfields
    newstruct.(fields{ii}) = [];
end
newstruct(nvars) = newstruct;

for ii = 1:nvars
    for jj = 1:nfields
        newstruct(ii).(fields{jj}) = oldworkspace.(varnames{ii}).(fields{jj});
    end
end

给我们:

yay

耶。

答案 1 :(得分:0)

不确定您的情况是否绝对需要通过字符串名称动态调用变量。 eval可以解决您的问题。但是,eval很慢。有时,它是不可靠的。在构建项目的各种组件时,您可以轻松地获得冲突的代码。根据我的经验,eval一直有替代品。在您的情况下,Adriaan在他的评论中概述了一个例子。

由于您只是尝试与第三方工具箱进行交互,如果您阅读的变量数量合理,您可以使用eval执行以下操作。

array=struct;

for i=1:length(structures)
  eval(['array(',num2str(i),').field2=',structures{i},';'])
end

如果您知道所有结构都命名为struct_#,那么您也可以

array=struct;

num=3; % the number of outputs from your toolbox
for i=1:num
  eval(['array(',num2str(i),').field2=struct_',num2str(i),'.field2;'])
end

请注意,您的field2值都是数组。您不能只创建一个数组并期望每个“单元格”携带另一个数组值。 Matlab中的数组,或者更确切地说 matrices 是一种特殊的数据类型。它们只取数值。 (矩阵在Matlab中以各种方式进行了高度优化。这就是我们使用Matlab的原因。)

另请注意,当您设置结构字段的相等性时,相等性是通过引用。没有数据的深层副本。修改一个将修改另一个。 (请注意这一点,但不一定要依赖它。决定何时深入复制事物是我们让Matlab处理的事情之一。)

同样,请注意who的结果。您需要完全清楚本地范围内的内容。以上假设您调用structures=who(str*)的结果对您的申请是正确的。