【问题标题】:How to call the dynamic variable that created from looping in Matlab?如何调用Matlab中循环创建的动态变量?
【发布时间】:2018-04-15 17:07:10
【问题描述】:

我使用循环方法创建了 4 个数组:

n=4;
for i=1:n
eval(['Bucket' num2str(i) '= []'])
end

所以输出的数组是:

Bucket1=[]
Bucket2=[]
Bucket3=[]
Bucket4=[]

如果我有一个循环函数,例如:

while a<n
   Bucket1 = 'Hello world';
   a=a+1;
end

那么我如何将 Bucket1 替换为动态变量?例如,当 a 等于 1 时,Hello World 将直接存储在 Bucket1 中。这意味着 Bucket1 的变量名称不是硬编码。

谁能与我分享想法?因为我是 Matlab 新手。

【问题讨论】:

  • 为什么不使用Bucket = zeros(1,4);Bucket = cell(1,4); 并避免所有这些?
  • 因为在后面的部分,不同的bucket需要分配不同的函数,所以这是从这个开始的要求,那么关于如何调用变量的任何想法?
  • 如果您使用这样的 eval,这表明您的代码设计不佳。您应该使用元胞数组Bucket = cell (1,4) 然后Bucket {a} = 'Hello World'。单元格可以保存不同的数据类型,并且更容易编码...... eval 很混乱,很难调试
  • 动态变量名在 MATLAB 中非常非常糟糕。如果您现在仍在学习:请从正确学习开始,从而避免他们。阅读this answer of mine 和其中包含的参考资料,为什么要这样做。
  • 作为 MATLAB 新手,您可能应该听取所提供的建议。动态变量名只会导致这样的问题,而使用包含相似元素的数组很容易使用for 循环进行迭代。说到这里,为什么选择使用while 循环并显式增加迭代次数,而不是使用自动为您递增的for 循环?

标签: matlab loops variables dynamic


【解决方案1】:

这可以使用assignin 来完成,如下所示,

    a=1;
    while a<=n
    assignin('base',['Bucket', num2str(a)], 'Hello world');
    a=a+1;
    end

【讨论】:

  • 请不要沉迷于人们的eval 习惯。而是使用单元格或结构给他们一个答案,而不是eval,因为这只会告诉他们动态变量名是好的,而他们绝对不是。
  • 你是绝对正确的@Adriaan,但似乎 OP 故意要求动态变量名,我不适合教他/她编程。
  • 您实际上处于那个位置,因为您在 Stack Overflow 上回答他们的问题。我认为他们会从这个答案中学到东西,因此:你教给他们一些东西。
【解决方案2】:

鉴于使用动态变量是一种不好的做法(如上述 cmets 所述),在可能的“替代”解决方案中(这些也已在上述 cmets 中提出)使用 struct 数据类型可以考虑加上dynamic field names的使用。

dynamic field names 的优势在于可以“以编程方式”定义变量的名称(在这种情况下将是结构的字段),避免 eval 隐含的潜在危险。

此外,struct 的使用允许通过使用非常大的 related functions 集合以编程方式管理其字段及其内容。

在下面的“疯狂”实现中,dynamic field names 概念用于创建一组变量作为结构的字段。

特别是,代码允许创建:

  • 一组变量(结构的字段),其名称在单元阵列中定义:

    dynamic_vars={'Bucket','another_var','one_more_var'}

  • 然后可以为每个变量指定数量(例如,4 Bucket =&gt; Bucket_1, Bucket_2, ...。数量在数组中指定

how_many=[4 3 2]

  • 然后可以在单元格数组中指定变量的类型(doublecharcell

var_type={'double' 'char' 'cell'}

  • 对于上述每个变量/结构的字段,可以通过zerosnanonesstring 等函数指定初始化它们的方法

init_set={'NaN' 'Hellp World' 'zeros'}

  • 要完成变量的定义和初始化,可以使用单元数组设置它们的size

var_dim={[2 3] -1 [1 3] [2 3]}

这是完整的代码:

% Define the name of the variable
dynamic_vars={'Bucket','another_var','one_more_var'}
% Define how many variables to be created with the "dynamic_vars" names
how_many=[4 3 2]
% Define the type of the variable to be created
var_type={'double' 'char' 'cell'}
% Define the function or string to be used to initialize the variables
init_set={'NaN' 'Hellp World' 'zeros'}
%init_set={'NaN' 'Hellp World' 'char'}
% Define the size of the dynamic_vars tobe created
% In the case of cellarray:
%    if cellarray of "number" two dimension have to be provided:
%       size of the cellarray 
%       size of the content of the cellarray
%    if cellarray of string to specify:
%       the size of the cellarray
%       the string to be used to initialize the cellarray
var_dim={[2 3] -1 [1 3] [2 3]}
%var_dim={[2 3] -1 [1 3] 'dummy_str'}
n_var=length(dynamic_vars)
% Loop over the variables to be created
for i=1:n_var
   % Loop over the number of variables to be created
   for j=1:how_many(i)
      % Select the data type of the variable
      switch(var_type{i})
         % Create the i-th variable of the j-th type and iknitialize it
         case 'double'
            switch(init_set{i})
               case 'zeros'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=zeros([var_dim{i}])
               case 'NaN'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=nan([var_dim{i}])
               case 'ones'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=ones([var_dim{i}])
               case 'rand'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=rand([var_dim{i}])
               otherwise
                  disp('ERROR: Unvalid init_set')
                  return
            end
        case 'char'
            my_data.([dynamic_vars{i} '_' num2str(j)])=init_set{i}
         case 'cell'
 switch(init_set{i})
               case 'char'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({var_dim{i+1}},[var_dim{i}])
               case 'zeros'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({zeros(var_dim{i+1})},[var_dim{i}])
               case 'NaN'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({nan(var_dim{i+1})},[var_dim{i}])
               case 'ones'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({ones(var_dim{i+1})},[var_dim{i}])
               case 'rand'
                  my_data.([dynamic_vars{i} '_' num2str(j)])=repmat({rand(var_dim{i+1})},[var_dim{i}])
               otherwise
                  disp('ERROR: Unvalid init_set')
                  return
            end
         otherwise
            disp('ERROR: Unvalid data type')
            return
      end
   end
end

my_data

生成具有以下字段的结构my_data

Bucket_1
Bucket_2
Bucket_3
Bucket_4
another_var_1
another_var_2
another_var_3
one_more_var_1
one_more_var_2

初始化如下:

Bucket_1 =

   NaN   NaN   NaN
   NaN   NaN   NaN

Bucket_2 =

   NaN   NaN   NaN
   NaN   NaN   NaN

Bucket_3 =

   NaN   NaN   NaN
   NaN   NaN   NaN

Bucket_4 =

   NaN   NaN   NaN
   NaN   NaN   NaN
   
another_var_1 = Hellp World
another_var_2 = Hellp World
another_var_3 = Hellp World

one_more_var_1 =
{
  [1,1] =

     0   0   0
     0   0   0

  [1,2] =

     0   0   0
     0   0   0

  [1,3] =

     0   0   0
     0   0   0
} 

警告

  • 必须添加对输入一致性的控制(例如,dynamic_varshow_many 的长度必须相同,...)
  • 代码已经用 Octave 4.2.1 测试过

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 2012-01-05
    • 1970-01-01
    • 2021-04-09
    相关资源
    最近更新 更多