Page 1 of 1

[SOLVED] multidimensional array - loop through 1st dimension

Posted: Wed Aug 10, 2005 5:38 am
by batfastad
Hi guys

I decided to completely ignore the "if it ain't broke don't fix it" rule some of our intranet pages.
I've only been developing in PHP for almost a year and I got a bit cocky, thinking I was better at arrays that I am.

In my code I used to perform a database query, which would return an array with my values.
The array was a single dimension, with each array item, containing 8 different values separated by ||||| as a delimiter.

Then I did a foreach loop, and exploded the array value based on the ||||| delimiter, then parsing the values into separate variables.

Code: Select all

foreach ($dbarray as $key => $arrayvalue) {

	// EXPLODE OUR ARRAY
	$arrayvalueexp = explode("|||||", $arrayvalue);

	$recordid = $arrayvalueexp[0];
	$companyname = $arrayvalueexp[1];
	$telephonenum = $arrayvalueexp[2];

	echo $recordid." ".$companyname." ".$telephonenum;

}
This worked fine
I thought I'd try and tidy my code up a bit.
I am under the impression that for this kind of stuff, multidimensional arrays are the way to go - for performance and ease of management.


So now I have my array being sent to me in this format (I've checked this using print_r)...

Code: Select all

$dbarray[0][0] = "recordid";
$dbarray[0][1] = "companyname";
$dbarray[0][2] = "telephonenum";
$dbarray[1][0] = "recordid1";
$dbarray[1][1] = "companyname1";
$dbarray[1][2] = "telephonenum1";
$dbarray[2][0] = "recordid2";
$dbarray[2][1] = "companyname2";
$dbarray[2][2] = "telephonenum2";
So I changed my loop code to this...

Code: Select all

foreach ($dbarray as $key => $arrayvalue) {

	$recordid = $arrayvalue[0];
	$companyname = $arrayvalue[1];
	$telephonenum = $arrayvalue[2];

	echo $recordid." ".$companyname." ".$telephonenum;

}
Unfortunately, now obviously the loop iterates through the first dimension, and then through the second dimension as well, so I now get 9 record lines instead of the 3 I had before.
Because the foreach loop effectively runs 9 times, whereas I only want it to run on the first dimension of the data.

How can I change my loop so that I only iterate though the first dimension, then access the vars from the second dimension directly (without a nested loop) from within my loop?

Is that possible?
Or am I barking up the wrong tree and should continue to just explode my array value as before.

I just thought it was about time I tackled this issue - despite reading many tutorials on the net, I've never felt comfortable with multidimensional arrays.
So an explanation of how to solve this problem would be very much appreciated.


Thanks

Ben

Posted: Wed Aug 10, 2005 5:59 am
by josh

Code: Select all

list($data, $data, $data) = mysql_fetch_array($result);

Posted: Wed Aug 10, 2005 6:15 am
by batfastad
That's a useful function, list()
Unfortunately my database is not MySQL - but I can use an array on the right side of that function anyway.

So I've changed my code to this...

Code: Select all

foreach ($dbarray as $key => $arrayvalue) {

    list($recordid, $companyname, $telephonenum) = $arrayvalue[$key];

    echo $recordid.", ".$companyname.", ".$telephonenum;

}
But my array is still looping over each item in the 2nd dimension.

The output I'm getting is...

Code: Select all

recordid, , 
, companyname, 
, , telephonenum

recordid1, , 
, companyname1, 
, , telephonenum1

recordid2, , 
, companyname2, 
, , telephonenum2
Rather than just 3 lines of output with the values separated by commas.

Is a foreach loop the one I need?
I only want to loop over different values of the 1st dimension, so I don't want to loop 3 times when the key of the 1st dimension is 0

Basically I'm looking for what's acknowledged as the most efficient way to perform this sort of loop.

Posted: Wed Aug 10, 2005 6:27 am
by onion2k

Code: Select all

$dbarray[0][0] = "recordid";
$dbarray[0][1] = "companyname";
$dbarray[0][2] = "telephonenum";
$dbarray[1][0] = "recordid1";
$dbarray[1][1] = "companyname1";
$dbarray[1][2] = "telephonenum1";
$dbarray[2][0] = "recordid2";
$dbarray[2][1] = "companyname2";
$dbarray[2][2] = "telephonenum2";

foreach ($dbarray as $x => $array) {
	echo $x . " - " . $array[0] . " - " . $array[1] . " - " . $array[2] . "<br>";
}

Code: Select all

0-recordid - companyname - telephonenum
1-recordid1 - companyname1 - telephonenum1
2-recordid2 - companyname2 - telephonenum2

Re: multidimensional array - loop through 1st dimension only

Posted: Wed Aug 10, 2005 6:41 am
by timvw
batfastad wrote: I decided to completely ignore the "if it ain't broke don't fix it" rule some of our intranet pages.
Time to read a decent book/take a course on data normalization.
Apparently you're not the only one that could take advantage of this..
http://www.thedailywtf.com/forums/39000/ShowPost.aspx


A good place to start: http://www.oreilly.com/catalog/javadtab ... r/ch02.pdf

Posted: Wed Aug 10, 2005 7:43 am
by batfastad
Ok so it turns out my loop was corrent - and doing exactly what I meant it to.

It's my array that was the problem, despite checking it :oops: :oops: :oops:
It's actually structured like this...

Code: Select all

$dbarray[0][0] = "recordid";
$dbarray[1][0] = "companyname";
$dbarray[2][0] = "telephonenum";
$dbarray[3][0] = "recordid1";
$dbarray[4][0] = "companyname1";
$dbarray[5][0] = "telephonenum1";
$dbarray[6][0] = "recordid2";
$dbarray[7][0] = "companyname2";
$dbarray[8][0] = "telephonenum2";

My database is FileMaker, so the data is stored behind the scenes in a very organised manner after 5 years of constant development.

So my problem now is how I construct my array.

So a quick rewrite of my FileMaker CDML (the web data language of FileMaker) template file...
The FM CDML tags get processed before the PHP.

Code: Select all

[FMP-Record]
$tagarray[[FMP-CurrentRecordNumber]][] = "[FMP-Field: RECORDID]";
$tagarray[[FMP-CurrentRecordNumber]][] = "[FMP-Field: COMPANYNAME]";
$tagarray[[FMP-CurrentRecordNumber]][] = "[FMP-Field: TELEPHONENUM]";
[/FMP-Record]
Gets it sorted.
The FMP-CurrentRecordNumber CDML tag keeps the key of the 1st dimension constant for this record.

Before this, it was adding each field value as a new element in the 1st dimension, and not the 2nd dimension - causing my array to be structured as above.


Don't worry, my database data is very organised but things did get confusing when manipulting the data in PHP - because I didn't know how to loop through multidimensional arrays properly.
Now I do, and the code reads loads better.

There's also a 1 second speed increase I've noticed as well, when dealing with 15,000 records.

Marked the subject as solved.

Thanks so much for all your help guys

Ben