1
votes

In MQL4, I could use the following function to print values from a two-dimensional array:

string Arr2ToString(double& arr[][], string dlm = ",", int digits = 2) {
  string res = "";
  int i, j;
  for (i = 0; i < ArrayRange(arr, 0); i++) {
    res += "[";
    for (j = 0; j < ArrayRange(arr, 1); j++) {
      res += StringFormat("%g%s", NormalizeDouble(arr[i][j], digits), dlm);
    }
    res = StringSubstr(res, 0, StringLen(res) - StringLen(dlm));
    res += "]" + dlm;
  }
  res = StringSubstr(res, 0, StringLen(res) - StringLen(dlm));
  return res;
}

However in MQL5 (version 5.00, build 1966), above function no longer works and it errors with:

'[' - invalid index value Array.mqh

in the first line when arr[][] is passed.

I've checked and MQL5 no longer allows passing an array with no dimension sizes.

When passing multidimensional arrays to a function, dimension sizes (except for the first one) should be specified:

double var[][3][3];
void Func(double &arg[][3][3]){    // ... }

Source: MQL5 PROGRAMMING BASICS: ARRAYS.

This doesn't make sense.

Assuming I don't know the size of my array (as I want to re-use this function for multiple array types, and defining dozens of separate functions for each size is ridiculous), how it is possible now to print values from a multidimensional array storing double values (such as two-dimensional array as example)?

1
Yes it is true we cannot pass multi-dimension array to our functions, but if you simply need to print the array you can use the ArrayPrint() function mql5.com/en/docs/array/arrayprintTheLastStark
@TheLastStark Do you think ArrayPrint() supports two-dimensional arrays? From the docs, it isn't clear.kenorb
it does I have tried it, MQL5 functions work with multi-dimensional arraysTheLastStark
You can post it as an answer as well (at least it answers the main title question), as I wasn't aware of it. Pity, that you can't get string out of it (so you can't use it with files, like storing array values in plain format), it forces you to print it.kenorb
I did add it as an answer, but yeah you are right, it is kind of sad too see they have put this restriction, I am very curious to know why the restriction is on MQL5 onlyTheLastStark

1 Answers

1
votes

I know this is not ideal, but we can use ArrayPrint() to print array. Refer here for the documentation

void  ArrayPrint( 
   const void&   array[],             // printed array 
   uint          digits=_Digits,      // number of decimal places 
   const string  separator=NULL,      // separator of the structure field values 
   ulong         start=0,             // first printed element index 
   ulong         count=WHOLE_ARRAY,   // number of printed elements 
   ulong         flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN     
   );

Here is another approach to pass multi-dimentional array to a function, again it is not ideal, but it works properly.

//+------------------------------------------------------------------+
//| Struct that is used to hold multi-dimentional array              |
//+------------------------------------------------------------------+
template<typename T>
struct MultiDimentionalArray
  {
   T                 index2[];      
  };
//+------------------------------------------------------------------+
//| Array print function that accepts MultiDimentionalArray struct   |
//+------------------------------------------------------------------+
string Arr2ToString(MultiDimentionalArray<double> &arr[],string dlm=",",int digits=2)
  {
   string res="";
   int i,j;
   for(i=0; i<ArraySize(arr); i++)
     {
      res+="[";
      for(j=0; j<ArraySize(arr[i].index2); j++)
        {
         res+=StringFormat("%g%s",NormalizeDouble(arr[i].index2[j],digits),dlm);
        }
      res = StringSubstr(res,0,StringLen(res) - StringLen(dlm));
      res+= "]" + dlm;
     }
   res=StringSubstr(res,0,StringLen(res)-StringLen(dlm));
   return res;
  }

Here is an example execution

void OnStart()
  {
//--- Declaring an array
   MultiDimentionalArray<double> arr[];

//--- Adding values to the array
   for(int i=0;i<10;i++)
     {
      //--- Resizing the array - 1st dimention
      if(ArraySize(arr)<=i) ArrayResize(arr,ArraySize(arr)+1);

      for(int j=0;j<10;j++)
        {
         //--- Resizing the array - 2nd dimention
         if(ArraySize(arr[i].index2)<=j) ArrayResize(arr[i].index2,ArraySize(arr[i].index2)+1);
         arr[i].index2[j]=i*j;
        }
     }

//--- Getting the result as string
   string arrResult=Arr2ToString(arr);
//--- Printing the result string
   Print(arrResult);
  }

Here is the result I got in the experts tab, from the execution of the above code

2019.06.11 16:25:47.078 Arrays (EURUSD,H1)  [0,0,0,0,0,0,0,0,0,0],[0,1,2,3,4,5,6,7,8,9],[0,2,4,6,8,10,12,14,16,18],[0,3,6,9,12,15,18,21,24,27],[0,4,8,12,16,20,24,28,32,36],[0,5,10,15,20,25,30,35,40,45],[0,6,12,18,24,30,36,42,48,54],[0,7,14,21,28,35,42,49,56,63],[0,8,16,24,32,40,48,56,64,72],[0,9,18