-3

I have 4 array create by using looping method:

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

So the array of the output is:

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

then if I have a looping function for example:

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

So how i can replace the Bucket1 to a dynamic variable? For example when a is equal to 1 then the Hello World will direct store in Bucket1. That's meant The variable name which is Bucket1 is not hard coding.

Can anyone share ideas with me? because I new to Matlab.

Shi Jie Tio
  • 2,479
  • 5
  • 24
  • 41
  • 5
    Why not use `Bucket = zeros(1,4);` or `Bucket = cell(1,4);` and avoid all of this? – TroyHaskin Nov 03 '17 at 03:01
  • because at the later part, differnt bucket need assign with diffrent function , so this is the requirement to start with this, so any idea on how to call the variable? – Shi Jie Tio Nov 03 '17 at 03:04
  • 5
    If you are using evals like this it is a sign you have your code deisgned poorly. You should use cell array `Bucket = cell (1,4)` then `Bucket {a} = 'Hello World'`. Cells can hold different data types and its easier to code... eval is messy and becomes hard to debug – Aero Engy Nov 03 '17 at 03:45
  • 5
    Dynamic variable names are very, very bad in MATLAB. If you're still learning now: please, start by learning it properly and thus ***AVOID*** them. Read [this answer of mine](https://stackoverflow.com/a/32467170/5211833) and references contained therein why you should do this. – Adriaan Nov 03 '17 at 07:03
  • Being new to MATLAB, you should probably listen to the advice that you're being given. Dynamic variable names simply cause problems like this, whereas using arrays holding like elements are easy to iterate over using a `for` loop. Speaking of which, why have you chosen to use a `while` loop and explicitly increment the iteration count rather than using a `for` loop that increments automatically for you? – beaker Nov 03 '17 at 16:11

2 Answers2

1

Given that the use of dynamic variable is a bad practice (as stated in the above comments), among the possible "alternative" solution (these also, already suggested in the above comments) the use of the struct data type can be considered coupled with the use of the dynamic field names.

The advantage of the dynamic field names consists in having the possibility to "programmatically" define the names of the variables (which in this case will be the field of the struct) avoiding the potential danger implied by eval.

Also the use of a struct allows to manage its field and their content programmatically by using the very large set of related functions.

In the following "crazy" implementation, the dynamic field names concept is used to create a set of variables as fields of a struct.

In particular, the code allows to create:

  • a set of variables (struct's field) whose name are defined in a cellarray:

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

  • for each of the variables, is then possible to specify the number of (that is, for example, 4 Bucket => Bucket_1, Bucket_2, .... The quantity is specified in an array

how_many=[4 3 2]

  • then it is possible to specify, in a cellarray the type of the variables (double, char, cell)

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

  • for each of the above varaibles / struct's field is possible to specify a way to initialize them through functions such as zeros, nan, ones or a string

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

  • to complete the definition and initialization of the variables, it is possible to set their size using a cellarray:

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

This is the full code:

% 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

which generate the struct my_data with the following fields:

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

Initialized as follows:

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
} 

Caveat

  • Controls on the consistency of the input (e. g. the length of dynamic_vars and how_many must be the same, ...) have to be added
  • The code has been tested with Octave 4.2.1
Community
  • 1
  • 1
il_raffa
  • 5,090
  • 129
  • 31
  • 36
0

This can be done using assignin as follows,

    a=1;
    while a<=n
    assignin('base',['Bucket', num2str(a)], 'Hello world');
    a=a+1;
    end
Hazem
  • 380
  • 1
  • 5
  • 14
  • 3
    Please don't indulge people with their `eval` habits. Rather give them an answer using cells or structures, but not `eval`, as that only teaches them dynamic variable names are good, which they most definitely are not. – Adriaan Nov 03 '17 at 07:04
  • You are absolutely right @Adriaan, but it seems like OP has asked for dynamic variable names purposely, and I am not in the right place to teach him/her programming. – Hazem Nov 03 '17 at 07:22
  • 1
    You actually are in that position, since you're answering their question on Stack Overflow. I assume they'll learn from this answer, ergo: you taught them something. – Adriaan Nov 03 '17 at 07:38