Discussion of article "MQL5 Programming Basics: Arrays" - page 2

 
A very helpful well-explained article, thankyou Dmitry Fedoseev.
 
How to return an array from a function? I found a workaround, but obviously there must be a way to do it "head-on" )).
 
thejobber:
How to return an array from a function? I've found a workaround so far, but obviously there must be a way to do it "head-on" )).

There is no way to do it head-on... except for a pointer to the array. For example:

CArrayDouble *Function(void);

Not head-on, but quite a standard approach, like this, in this section:

void Function(double &_arr_out[]);
In general, the returned array is a parameter-reference...
 

Yeah, thanks. I tried to just immediately

return *x; out of habit, like in C++ ))

instead of

return GetPointer(x)

figured it out ))

 
MetaQuotes Software Corp.:

New article MQL5 Programming Basics: Arrays is published:

Author: Dmitry Fedoseev

1 Question:

#define SIZE_X 3;

(...)

int ArrayName[SIZE_X];

Compiler forbids such construction. Why?

 
Many thanks for this extended review
 
#import "dll.dll"
  double qwerty(double &q[]);
#import

I'm making a dll and I want to pass an array pointer to it.

But I can't figure out how to do it.

Something's wrong.


I need some analogue of C++


double qwerty(double *q);

double *q;

q = new double [100];

qwerty(q);


How to do it in MQL5...

 
In mql, whatever array there is, that's what it is, you can't do anything with it. There should not be any problems. The error is somewhere near in your dll. Maybe you should pass the array size in the dll.
 

Thanks for your code it saved me some time to write. I ried to use the MQL5 Array object (double,int etc.) and I just got frustrated. I came to your post and found your code to resize the arrays that was awesome thanks. I modified your code to cater for any data type. Just dont try to use the Contains (Search method) method for objects as it might not work as objects might be references, not sure I haven't tested this. I'm trying to recreate C# inside MQL5 hence the abbreviations are similar :)


God Bless !!!



// + ----------------------------------------------- ------------------- + 


// | 
CDynamicArray.mqh | 


// | 
Integer | 


// | 
https://login.mql5.com/ru/users/Integer | 


// + ----------------------------------------------- ------------------- + 


#property 

copyright  

"Integer" 


#property 

link  

"https://login.mql5.com/en/users/Integer" 


// + - -------------------------------------------------- --------------- + 


// | 
| 


// + ----------------------------------------------- ------------------- + 


template 

< 

typename 

 T> 


class 

 CDynamicArray 


  { 


private 

 : 
   

int 

                m_ChunkSize;     

// Chunk size 
   

int 

                m_ReservedSize; 

// Actual size of the array 
   

int 

                m_Size;         

// Number of active elements in the array 


public 

 : 


   T Element [];       

// The array proper. 
It is located in the public section, 
                                     

// so that we can use it directly, if necessary 
   

// + --------------------------- --------------------------------------- + 
   

| 
Constructor | 
   

// + ----------------------------------------------- ------------------- + 
   

void 

 CDynamicArray ( 

int 

 ChunkSize = 

1024 

 ) 


     { 


      m_Size = 

0 

 ;                             

// Number of active elements 


       m_ChunkSize = ChunkSize;               

// Chunk size 


       m_ReservedSize = ChunkSize;             

// Actual size of the array 
      

ArrayResize 

 (Element, m_ReservedSize); 

// Prepare the array 


      } 
   

// + ----------------------------------------- ------------------------- + 
   

// | 
Function for adding an element at the end of array | 
   

// + ----------------------------------------------- ------------------- + 
   

void 

 Add (T Value) 


     { 


      m_Size ++; 

// Increase the number of active elements 
      

if 

 (m_Size> m_ReservedSize) 


        { 

// The required number is than the actual array size 


          m_ReservedSize + = m_ChunkSize; 

// Calculate the new array size 
         

ArrayResize 

 (Element, m_ReservedSize); 

// Increase the actual array size 


         } 


      Element [m_Size- 

1 

 ] = Value; 

// Add the value 


      } 
     
     

void 

 Set ( 

int 

 index, T Value) 


     { 


      m_Size ++; 

// Increase the number of active elements 
      

if 

 (m_Size <index) 


        { 
         

return 

 ; 


        } 


      Element [index] = Value; 

// Add the value 


      } 
   

// + ----------------------------------------- ------------------------- + 
   

// | 
Function for getting the number of active elements in the array | 
   

// + ----------------------------------------------- ------------------- + 
   

int 

 Count () 


     { 
      

return 

 (m_Size); 


     } 
   


   T 

operator 

 [] ( 

const  

int 

 index) 

const 

 { 

return 

 Element [index]; 
} 
   
   

bool 

Contains (T itemToFind) 


   { 
      

for 

 ( 

int 

 i = 

0 

 ; i <Count (); i ++) 


        { 
            

if 

 (Element [i] == itemToFind) 


            { 
               

return  

true 

 ; 


            } 


        } 
        
      

return  

false 

 ; 


   } 
   
   

int 

 IndexOf (T itemToFind) 


   { 
      

for 

 ( 

int 

 i = 

0 

 ; i <Count (); i ++) 


        { 
            

if 

 (Element [i] == itemToFind) 


            { 
               

return 

 i; 


            } 


        } 
        
      

return 

 - 

1 

 ; 


   } 


  }; 


// + ----------------------------------------------- ------------------- + 

Then you can declare them like so:

CDynamicArray 

< 

int 

> 

  *Tickets; 


CDynamicArray 

< 

bool 

> 

 *FixedSLUsed; 


CDynamicArray 

< 

bool 

> 

 *PrevBarSLUsed; 

and create them like:

                        Tickets = 

new 

 CDynamicArray< 

int 

>(); 


                        FixedSLUsed = 

new 

 CDynamicArray< 

bool 

>(); 


                        PrevBarSLUsed = 

new 

 CDynamicArray< 

bool 

>(); 

and in the code you use them like a normal class:



int 

 ticket = 

PositionGetInteger 

 ( 

POSITION_TICKET 

 ); 


int 

 index; 


if 

 (!Tickets.Contains(ticket)) // If Ticket Object does NOT contains ticket then we go into the if 


{ 


        Tickets.Add(ticket); 


        FixedSLUsed.Add( 

false 

); 


        PrevBarSLUsed.Add( 

false 

); 


} 
      


index = Tickets.IndexOf(ticket);   
 

ok lets try the english version of MQL.


Thanks for your code post. It saved me time. I tried using the MQL arrays and they were confusing. I then was very depressed that I need to once again need to write basic structures that was supposed to be there BUT then I found your code that saved me some research time on arrays and how to make them grow\increase dynamically. AWESOME thanks.

I hope i can give back to you! the code below works for all data types. It will work on objects too but the Contains (search) method might not work. I only tested it on types (double, int, bool). String might give you problem as well and the code might need to be extended.


//+------------------------------------------------------------------+
//|                                                CDynamicArray.mqh |
//|                                                          Integer |
//|                          https://login.mql5.com/ru/users/Integer |
//+------------------------------------------------------------------+
#property copyright "Integer"
#property link "https://login.mql5.com/ru/users/Integer"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
template <typename T>
class CDynamicArray
  {
private:
   int               m_ChunkSize;    // Chunk size
   int               m_ReservedSize; // Actual size of the array
   int               m_Size;         // Number of active elements in the array
public:
   T                 Element[];      // The array proper. It is located in the public section, 
                                     // so that we can use it directly, if necessary
   //+------------------------------------------------------------------+
   //|   Constructor                                                    |
   //+------------------------------------------------------------------+
   void CDynamicArray(int ChunkSize=1024)
     {
      m_Size=0;                            // Number of active elements
      m_ChunkSize=ChunkSize;               // Chunk size
      m_ReservedSize=ChunkSize;            // Actual size of the array
      ArrayResize(Element,m_ReservedSize); // Prepare the array
     }
   //+------------------------------------------------------------------+
   //|   Function for adding an element at the end of array             |
   //+------------------------------------------------------------------+
   void Add(T Value)
     {
      m_Size++; // Increase the number of active elements
      if(m_Size>m_ReservedSize)
        { // The required number is bigger than the actual array size
         m_ReservedSize+=m_ChunkSize; // Calculate the new array size
         ArrayResize(Element,m_ReservedSize); // Increase the actual array size
        }
      Element[m_Size-1]=Value; // Add the value
     }
     
     void Set(int index, T Value)
     {
      m_Size++; // Increase the number of active elements
      if(m_Size<index)
        { 
         return;
        }
      Element[index]=Value; // Add the value
     }
   //+------------------------------------------------------------------+
   //|   Function for getting the number of active elements in the array|
   //+------------------------------------------------------------------+
   int Count()
     {
      return(m_Size);
     }
   
   T operator[](const int index) const { return Element[index]; }
   
   bool Contains(T itemToFind)
   {
      for(int i=0;i<Count();i++)
        {
            if(Element[i] == itemToFind)
            {
               return true;
            }
        }
        
      return false;
   }
   
   int IndexOf(T itemToFind)
   {
      for(int i=0;i<Count();i++)
        {
            if(Element[i] == itemToFind)
            {
               return i;
            }
        }
        
      return -1;
   }
  };
//+------------------------------------------------------------------+


Then you can declare it for all types you need like so:


//i declared them in my class like so
   CDynamicArray<int> *Tickets;
   CDynamicArray<bool> *FixedSLUsed;
   CDynamicArray<bool> *PrevBarSLUsed;


// Then I declared them in my class methods like so

   Tickets = new CDynamicArray<int>();
   FixedSLUsed = new CDynamicArray<bool>();
   PrevBarSLUsed = new CDynamicArray<bool>();

// and i used them in my class methods like so:
      int ticket = PositionGetInteger(POSITION_TICKET);
      int index;
      if(!Tickets.Contains(ticket))
      {
         Tickets.Add(ticket);
         FixedSLUsed.Add(false);
         PrevBarSLUsed.Add(false);
      }
      
      index = Tickets.IndexOf(ticket);  
//more code was removed



hope this helps anyone