Arrays are a Pain within the loop

 
Hello generous members of mql4 community. I'm starting to learn Arrays but they're getting nasty with me :) The 2 Dimension Array, Allerts just fine within the loop but would not print correctly outside the loop nor write the same values to file within the loop. Any Ideas why?
 

ubzen did you resolve your conundrum?

 
Oh yeah... Glad to see you're back Phillip :). Turns out the array would not keep the value unless the size was set. Duh lol !! The problem was I didn't know what the size was gonna be, I ended up using a slightly larger declaration for the array variable. And then when it's time to get the values. I just used the Loop illustration variable like (int i). So if it toke Ten i's to get all the values then there must be 10 Rows. There must be a easier way, I'll discover it one of these days. Hope this example helps someone in my shoes tho.
 

declare your array without setting a static size

double   MyArray[];
then resize the array prior appending the new value to it using ArrayResize, that way you algorithmically control the size of the array

post your specific loop code and I'll show you what I mean with code
 

Here it is. I've been trying to extract Html Contents out of web pages. I could have achieve this using string variables but really wanted a case study for arrays. I've heard arrays are more efficient for table like information. Maybe the more Data the better Arrays shine.

Note: I still cannot figure out how to get the File_Write to use double loop like Fund_Array1[a][b]. All my attempts results in File_Write inputting information in the file 1-element at a time. Instead of 1 Row of 10 elements at a time.

//#################################################################
//#################################################################
Pointer1=0; Pointer2=0;int b=0;int Rows;string Fund_Array1[99][10];
bool Stop_Loop=false;
for(a=0;a<=200;a++){
if(Stop_Loop==true){break;}
   Rows=a;
   Fund_Array1[a][0]=StringSubstr(Date_Content1,0,6);
//----------------------
for(b=1;b<=10;b++){
   if(StringFind(Date_Content1,"<td",Pointer2)==-1){
   Stop_Loop=true;break;}
   Pointer1=StringFind(Date_Content1,"<td",Pointer2);
   Pointer2=StringFind(Date_Content1,"</td",Pointer1);
   Fund_Array1[a][b]=
   StringSubstr(Date_Content1,Pointer1,Pointer2-Pointer1);
//--------
   Pointer1=StringFind(Fund_Array1[a][b],">",0)+1;
   Fund_Array1[a][b]=StringSubstr(Fund_Array1[a][b],Pointer1,0);
//--------
   Pointer1=StringFind(Fund_Array1[a][b],">",0)+1;
   Fund_Array1[a][b]=StringSubstr(Fund_Array1[a][b],Pointer1,0);
//--------
   if(StringFind(Fund_Array1[a][b],"</b>",0)>0)
   {Stop_Loop=true;break;}else{
   if(StringFind(Fund_Array1[a][b],"</Table>",0)>0)
   {Stop_Loop=true;break;}}
}}
//#################################################################
//#################################################################
File_Number2=FileOpen("Fund.csv",FILE_WRITE,',');
for(a=0;a<=Rows;a++){
FileWrite(
File_Number2,
Fund_Array1[a][0],
Fund_Array1[a][1],
Fund_Array1[a][2],
Fund_Array1[a][3],
Fund_Array1[a][4],
Fund_Array1[a][5],
Fund_Array1[a][6],
Fund_Array1[a][7],
Fund_Array1[a][8],
Fund_Array1[a][9]
);}FileClose(File_Number2);
//#################################################################
//#################################################################
 

OK, here's an example of some changes you could make to your code:

Pointer1=0; Pointer2=0;int b=0;string row_text;string Fund_Array1[][10]; // note Fund_Array1 is not initialized with a pre-set number of columns (the 1st dimension)
bool Stop_Loop=false;

// Let's add data to our dynamically growing array
      
for(a=0;a<=200;a++)
   { // loop "for(a=0;a<=200;a++)" start
   if(Stop_Loop==true) break;
      
   ArrayResize(Fund_Array1,a+1); // resize the array to have a+1 rows, use a+1 since your loop counter starts with a=0
      
   Fund_Array1[a][0]=StringSubstr(Date_Content1,0,6); // note we intentionally use a, not a+1, to address the column number since array addressing starts at zero
      
   //----------------------
   for(b=1;b<=10;b++)
      { // loop "for(b=1;b<=10;b++)" start
      
      //| do some stuff
      
      Fund_Array1[a][b]=StringSubstr(Date_Content1,Pointer1,Pointer2-Pointer1);
      
      //| do some stuff
      
      } // loop "for(b=1;b<=10;b++)" end
   } // loop "for(a=0;a<=200;a++)" end

// Let's write our array data to a file

File_Number2=FileOpen("Fund.csv", FILE_CSV|FILE_WRITE,',');

for(a=0;a<ArrayRange(Fund_Array1,0);a++) // let the loop determine for itself how big the array is and set the loop incrementer accordingly
   { // loop "for(a=0;a<ArrayRange(Fund_Array1,0);a++)" start
   row_text=""; initialize the row information
   for(b=1;b<=10;b++) // assemble the contents of the first row into a single element
      { // loop "for(b=1;b<=10;b++)" start
      row_text=StringConcatenate(row_text,Fund_Array1[a][b],","); // append the element [a][b] to the pre-existing string of row_text and add a "," to delimit the element in the string
      } // loop "for(b=1;b<=10;b++)" end

   FileWrite(File_Number2,row_text); // write the row to the file

   } // loop "for(a=0;a<ArrayRange(Fund_Array1,0);a++)" end

FileClose(File_Number2);

//#################################################################
//#################################################################
 
Ah, nice. You're the Man Phillip!! That ArrayResize and ArrayRange sure comes in handy. I'll be sure to give their Docs another look and modify my codes accordingly. Thanks.
 

I just realized there is an accounting discrepancy between your "b" loop incrementer and the actual number of declared rows...that and for some reason I kept stating "columns" when I was thinking and meaning to write "rows":

Pointer1=0; Pointer2=0;int b=0;string row_text;string Fund_Array1[][10]; // note Fund_Array1 is not initialized with a pre-set number of ROWS (the 1st dimension)
and
Fund_Array1[a][0]=StringSubstr(Date_Content1,0,6); // note we intentionally use a, not a+1, to address the ROW number since array addressing starts at zero
Notice we declared Fund_Array as having 10 columns, that means the address is from [a][0] to [a][9]...not [a][10] as that would be the 11th column.

Since we already pushed a value to the [a][0] element our b-loop needs to be:
for(b=1;b<=9;b++) // loop 1-9, not 1-10
and then when we assemble the row data into a single string we need to start the loop at zero:
for(b=0;b<=9;b++) // assemble the contents of the first row into a single element (loop 0-9 not 1-10 since b is also an array address)
 

1005phillip: ...Notice we declared Fund_Array as having 10 columns, that means the address is from [a][0] to [a][9]...not [a][10] as that would be the 11th column....

Hehe... Nice Ketch. Can't believe I'd never caught that. Now I wonder if the Break statement is the reason why it's been working. Index 0 is soo un.natural.

 

Not to C programmers. Write your loops like this:

#define STR_COUNT 10
string Fund_Array1[][STR_COUNT];
...
for(b=0;b<STR_COUNT;b++) // < no equal sign.
 
Ah, so that's how it's done in C. Another good example. Thanks WHRoeder.
Reason: