Multi parameter return value 'return( "string",double)

 
Hello guys. I created a string parser that uses a delimiter to extract multiple parameters from a string variable, or a string return value of a function. The results have to be typecasted to the corresponding types as they are stored in string array. Is there a better way to do this?

example:
void OnStart()
{
string name = "John";
isHeCleared(name);
}
//--- function to return if cleared, and date of clearance.
string datetime isHeCleared(string name, int idx)
{
        // search name in database
// return result and clearance date

return("cleared",D'June 1st);
}

Is there a different approach I can try, or is using my string parser enough?

If you need the parser, just ask.

 

Think about what you want to do... This is easy to do in python because everything in python is an object. What are you actually returning in python to achieve this? You aren't actually returning multiple things and instead its one object (tuple) of other things. So your options are return a collection object or use C patterns. In your use case it's better to use more a more common C pattern that returns a bool and changes the variable in-place. 

void OnStart() {
   string name = "John";
   datetime clear_date = NULL;
   if (isHeCleared(name, clear_date)) {
      Print(clear_date);
   }
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool isHeCleared(string name, datetime &clear_date) {
   if (StringFind(name, "o") >= 0) {
      clear_date = TimeCurrent();
      return true;
   }
   return false;
}
 
nicholi shen:

Think about what you want to do... This is easy to do in python because everything in python is an object. What are you actually returning in python to achieve this? You aren't actually returning multiple things and instead its one object (tuple) of other things. So your options are return a collection object or use C patterns. In your use case it's better to use more a more common C pattern that returns a bool and changes the variable in-place. 

I have a couple of workarounds. But I am specifically interested in such or any similar approach that can return more than one parameter in MQL. I'm trying to look for a simpler method that does not force me to write separate code to find out if the user is cleared, and another to find out the clearance date.

It is impossible to return arrays in MQ, that's why I created a parser. 

I like opening up to new ideas, that's why I asked for some info. The parser class I created takes in a string with defined delimiters, then stores the data in an array that can be accessed by the developer. Seems I'll have to settle for it in the mean-time.

 
Nelson Wanyama:

I have a couple of workarounds. But I am specifically interested in such or any similar approach that can return more than one parameter in MQL. I'm trying to look for a simpler method that does not force me to write separate code to find out if the user is cleared, and another to find out the clearance date.

It is impossible to return arrays in MQ, that's why I created a parser. 

I like opening up to new ideas, that's why I asked for some info. The parser class I created takes in a string with defined delimiters, then stores the data in an array that can be accessed by the developer. Seems I'll have to settle for it in the mean-time.

While it is possible it is not feasable. You can return a struct that wraps an array, but that's ugly and nobody will use it. As far as splitting a string by a delimiter, that already exists in the API. 

https://www.mql5.com/en/docs/strings/stringsplit

Documentation on MQL5: String Functions / StringSplit
Documentation on MQL5: String Functions / StringSplit
  • www.mql5.com
The number of substrings in the result[] array. If the separator is not found in the passed string, only one source string will be placed in the array. If string_value is empty...
 
int OnInit()
  {
//--- create timer
  // EventSetTimer(60);
    //check in aston martin
    Dudes.CheckIn("Aston","Martin",44,Time[10]);
    //check in james bond
    Dudes.CheckIn("James","Bond",55,Time[9]);
    //check in bill clinton
    Dudes.CheckIn("Bill","Clinton",71,Time[8]);
    //check out aston martin 
      //find index
      int idx=Dudes.FindIndex("Aston","Martin");
      Dudes.CheckOut(idx,Time[7]);
    
    //print
    string printation="";
    for(int x=0;x<Dudes.Total;x++)
    {
    clearance_data clr=Dudes.IsHeCleared_WithIdx(x);
    printation+=Dudes.Log[x].FirstName+" "+Dudes.Log[x].LastName+" "+clr.MessageToUser+"\n";
    }
    Alert(printation);
//---
   return(INIT_SUCCEEDED);
  }
//--- function to return if cleared, and date of clearance.
//The Dude Object 
enum dude_status
{
ds_cleared=0,//Cleared
ds_checked_in=1,//Checked In
ds_not_here=2//No Logs
};
struct dude_object
{
string FirstName,LastName;
int Age;
datetime CheckInDate,ClearanceDate;
dude_status Status;
dude_object(void){FirstName=NULL;LastName=NULL;Age=0;CheckInDate=0;ClearanceDate=0;Status=ds_not_here;}
void CheckIn(string first_name,
             string last_name,
             int age,
             datetime check_in_date)
     {
     FirstName=first_name;
     LastName=last_name;
     Age=age;
     CheckInDate=check_in_date;
     Status=ds_checked_in;
     }
void CheckOut(datetime check_out_date)
     {
     ClearanceDate=check_out_date;
     Status=ds_cleared;
     }
};
//The Dude Object Ends Here 
//The Log of Dudes , has a list of Dude Objects
  struct clearance_data
  {
  bool IsCleared;
  datetime ClearanceDate;
  string MessageToUser;
  clearance_data(void){IsCleared=false;ClearanceDate=0;MessageToUser="Initialized";}
  };
  struct dudelog
  {
  dude_object Log[];
  int Total,Size,Step;
  dudelog(void){Total=0;Size=0;Step=100;}
  dudelog(int size,int step){Total=0;Size=size;Step=step;ArrayResize(Log,Size,0);}
  ~dudelog(void){ArrayFree(Log);}
  void CheckIn(string first_name,string last_name,int age,datetime check_in_date)
          {
          Total++;
          if(Total>Size){Size+=Step;ArrayResize(Log,Size,0);}
          Log[Total-1].CheckIn(first_name,last_name,age,check_in_date);
          }
  void CheckOut(int idx_literal,datetime check_out_date)
          {
          if(idx_literal<Total&&Total>0)
            {
            Log[idx_literal].CheckOut(check_out_date);
            }
          } 
  int FindIndex(string first_name,string last_name)
          {
          for(int f=0;f<Total;f++)
             {
             if(first_name==Log[f].FirstName&&last_name==Log[f].LastName){return(f);}
             }
          return(-1);
          }   
  clearance_data IsHeCleared_WithIdx(int idx_literal)
          {
          clearance_data result;
          if(idx_literal>=Total) result.MessageToUser="Index is not valid";
          if(Total==0) result.MessageToUser="Log is empty";
          if(idx_literal<Total&&Total>0)
            {
            result.MessageToUser="Not Cleared";
            if(Log[idx_literal].Status==ds_cleared)
              {
              result.IsCleared=true;
              result.ClearanceDate=Log[idx_literal].ClearanceDate;
              result.MessageToUser="Cleared on "+TimeToString(result.ClearanceDate,TIME_DATE);
              }           
            }                   
          return(result);
          }
  clearance_data IsHeClearedWithInfo(string first_name,string last_name)
          {
          clearance_data result;
          if(Total==0) result.MessageToUser="Log is empty";
          if(Total>0) 
            {
            int idx=FindIndex(first_name,last_name);
            if(idx==-1) result.MessageToUser="Data Not In Log";
            if(idx!=-1)
              {
              result=IsHeCleared_WithIdx(idx);
              }
            }
          return(result);
          }
  };
  
  dudelog Dudes;

Also if you pass an array as reference you can return data to that array (returning arrays) 

So if you had 2 arrays ,or a structure/class array where the clearance bool and clearance date are to be passed you can reference it in the function like that 

void IsHeCleared(int idx,type_of_array &array[])
{
array[0]="accessed by function";
}

 
Nelson Wanyama: It is impossible to return arrays in MQ,

You pass the array into your function, by reference, and updated it; no need to return it. nicholi already show you how in #1

 
Lorentzos Roussos:

Also if you pass an array as reference you can return data to that array (returning arrays) 

So if you had 2 arrays ,or a structure/class array where the clearance bool and clearance date are to be passed you can reference it in the function like that 

Thank you. You really took sometime on this one. Let me take a keen look at it.

 
William Roeder:

You pass the array into your function, by reference, and updated it; no need to return it. nicholi already show you how in #1

Thank you, but you should know, I did not ask because I don't know of that method. I want new ideas, because despite of the existence of this method, I find it's implementation rather inefficient for my 'other' project. This here is a sample code. 

 

I started, but never fully finished a string class. Maybe you can get some ideas from this. 

 
nicholi shen:

I started, but never fully finished a string class. Maybe you can get some ideas from this. 

Thanks. This is very kind of you

 
Lorentzos Roussos:

Also if you pass an array as reference you can return data to that array (returning arrays) 

So if you had 2 arrays ,or a structure/class array where the clearance bool and clearance date are to be passed you can reference it in the function like that 

Thank you Lorentzos. I have picked up quite a bit from your code. 

I appreciate the effort and support.

Reason: