Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Quick way to retrieve key in array 2

Status
Not open for further replies.

Sleidia

Technical User
May 4, 2001
1,284
FR
Hi :)

Neurons not functioning here ! :(

I have an array that I fill with values inside a loop like this :

Code:
while ($row = mysql_fetch_array($sql_result[1])) {

$GLOBALS["site_pages"]["BASEDIR"][] = ...;
$GLOBALS["site_pages"]["SUBDIR"][] = ...;
$GLOBALS["site_pages"]["FILENAME"][] = ...; 

}

Now, what I'm trying to do is create a function that would output a value corresponding with the one present in its fist parameter.

It would be called like this :

Code:
test_function("filename.php", "SUBDIR"); // gets right subdir
test_function("some directory", "FILENAME"); // gets right filename

My bet is that I have to retrieve the key index of the data to be tested. But I would like to know if it is possible to design a function that doesn't have to loop through the whole array again.

Thanks for the help !
 

Hi Sleipnir :)

The problem with array_search() is that it doesn't work with multidimensional arrays.

Doing ...
array_search("some text", $GLOBALS["site_pages"])
... produces 0 when ...
array_search("some text", $GLOBALS["site_pages"]["SUBDIR"])
... outputs the right result.

In that case, traversing the array is the only solution?
Nothing more elegant exists?

 
$GLOBALS["site_pages"]["SUBDIR"]

is not multidimensional. It looks to me like you should be able to use the invocation:

$key = array_search ('filename.php', $GLOBALS['site_pages']['SUBDIR']);




Want the best answers? Ask the best questions! TANSTAAFL!
 

Sure, but I would like to apply the test/search on the whole $GLOBALS['site_pages']. Not $GLOBALS['site_pages']["SUBDIR"] because I would have to add one more argument in the function call.

Thanks anyway.
 
Well, I'm sorry but it's not what I'm trying to achieve.

My non-working function is this one :

Code:
function a_function($string, $param) {

$output = $GLOBALS["site_page"][$param][array_search($string, $GLOBALS["site_page"])];

return $output;

}

It doesn't work because array_search() can't traverse the whole array $GLOBALS["site_page"].
 
You are not expressing clearly what it is you are trying to achieve.

You want to hand the function two strings, one which is a search term and the other which is the name of a sub-array of the array $GLOBALS['site_pages'].

You then want the function to search what, the sub-array in question or the entire array?

And you want this function to return to you the very search string you've handed it?



Want the best answers? Ask the best questions! TANSTAAFL!
 
Sorry for not being clear enough :(

You want to hand the function two strings, one which is a search term and the other which is the name of a sub-array of the array $GLOBALS['site_pages'].

Exactly

You then want the function to search what, the sub-array in question or the entire array?

The entire array.

And you want this function to return to you the very search string you've handed it?

No, I want it to return the value contained in the sub-array that bears the same key number but whose name is the one found in the second argument fo the function call.

Let's say we have this :

Code:
$GLOBALS["site_pages"]["BASEDIR"][0] = "a";
$GLOBALS["site_pages"]["SUBDIR"][0] = "b";
$GLOBALS["site_pages"]["FILENAME"][0] = "c";

$GLOBALS["site_pages"]["BASEDIR"][1] = "d";
$GLOBALS["site_pages"]["SUBDIR"][1] = "e";
$GLOBALS["site_pages"]["FILENAME"][1] = "f";

my_function("a", "FILENAME") should return "c"
my_function("e", "BASEDIR") should return "d"

The goal is to store a whole sitemap in a session array and to, for example, construct a url form a filename.
Each information about one file is supposed to help to find any other information about this same file.
 
i can 't help thinking that restructuring your array so that it looks more like

site_pages
[1]
basedir=>a, subdir=>b, filename=>c

etc

would make your array more usable.

however i recently spent a day trying to get my head around optimising multi-dimensional arrays. my code was looping and testing the array three times to get one set of results needed to produce a report needed from a database that did not support group_concat. in the end i couldn't get it to work neatly so as a best alternative i created a looped sql call that queried the db 30 times (it was a calendar type application). i found that not only was this trivial coding but i suffered no discernable speed penalty - and this was before db optimisation including the application of any indices to the tables. i have filed this experience in the bucket i have named "purist coding ain't all it's cracked up to be".
 
So thinking of it as:
[tt]
BASEDIR SUBDIR FILENAME
0 a b e
1 d e f
[/tt]

The question becomes, "Search the entire array for the string. If found, return the value from the specified column in the same row as where the value was found".

Assuming that's right, try:

Code:
<?php

function foo ($needle, $column_name)
{
	$key = FALSE;
	$columns = array ('BASEDIR', 'SUBDIR', 'FILENAME');
	
	foreach ($columns as $column)
	{
		if ($key === FALSE)
		{
			$key = array_search ($needle, $GLOBALS['site_pages'][$column]);
		}
	}
	
	if ($key !== FALSE)
	{
		return $GLOBALS['site_pages'][$column_name][$key];
	}
	else
	{
		return FALSE;
	}
}
	
	
$GLOBALS["site_pages"]["BASEDIR"][0] = "a";
$GLOBALS["site_pages"]["SUBDIR"][0] = "b";
$GLOBALS["site_pages"]["FILENAME"][0] = "c";

$GLOBALS["site_pages"]["BASEDIR"][1] = "d";
$GLOBALS["site_pages"]["SUBDIR"][1] = "e";
$GLOBALS["site_pages"]["FILENAME"][1] = "f";


print foo("a", "FILENAME");
print '<br>';
print foo("e", "BASEDIR");
?>



Want the best answers? Ask the best questions! TANSTAAFL!
 
Thanks Sleipnir :)

I reckon that looping through the sub-arrays names is a better alternative than looping through all the rows.

Obviously, we absolutely need to use a loop somewhere.

Lastly, I just noticed that my idea wouldn't work as expected if values were not unique.

For example,

Code:
$GLOBALS["site_pages"]["BASEDIR"][0] = "a";
$GLOBALS["site_pages"]["SUBDIR"][0] = "e";
$GLOBALS["site_pages"]["FILENAME"][0] = "c";

$GLOBALS["site_pages"]["BASEDIR"][1] = "d";
$GLOBALS["site_pages"]["SUBDIR"][1] = "e";
$GLOBALS["site_pages"]["FILENAME"][1] = "f";

my_function("e", "FILENAME") // Ooops !
 
i can 't help thinking that restructuring your array so that it looks more like

site_pages
[1]
basedir=>a, subdir=>b, filename=>c

etc

would make your array more usable.

Hi Jpadie,

Sorry to ask but, in what way it would be more usable in comparison with the current method?

however i recently spent a day trying to get my head around optimising multi-dimensional arrays. my code was looping and testing the array three times to get one set of results needed to produce a report needed from a database that did not support group_concat. in the end i couldn't get it to work neatly so as a best alternative i created a looped sql call that queried the db 30 times (it was a calendar type application). i found that not only was this trivial coding but i suffered no discernable speed penalty - and this was before db optimisation including the application of any indices to the tables. i have filed this experience in the bucket i have named "purist coding ain't all it's cracked up to be".

Then, I guess I should simply quit using the session array and call the database everytime a link is output on the pages? Sounds crazy to me :)
 
Then, I guess I should simply quit using the session array and call the database everytime a link is output on the pages?
That's what I would have done. What's the point in having a database server if you're just going to implement your own database in PHP code?



Want the best answers? Ask the best questions! TANSTAAFL!
 

Wow ... I'm very surprised to read this, sleipnir !

I mean, I've always had the (false?) idea that it should be avoided to call the database too many times.

I thought that it was more "server-friendly" to use a session in that specific case.

Too bad I can't give more than one star per thread ;)
 
I look at it this way:

Teams of programmers at MySQL or PostgreSQL or Oracle or where-ever have spent untold man-hours to produce optimized compiled code to do what I would try to replicate in interpreted code.

You may be able to produce PHP code that rivals the efficiency of the code inside MySQL. I'm fairly certain, however, that I can't.




Want the best answers? Ask the best questions! TANSTAAFL!
 
i agree with sleipnir214 here.

also remember that a session is just a file in the filesystem. accessing it is a read operation. and the resultant session takes up RAM on the server. if your site is busy and you have, say 1000 active users then your entire site structure will be held in RAM 1000 concurrent times. the same data copied 1000 times in precious RAM... and then saved to the filesystem not just 1000 times but however many active sessions there are on your system (recent unique visitors).

the problem scales with your site complexity and the number of users, of course. compared to this a database call each time to ascertain the correct page to which the user is to be directed seems the better option.

i would have done this instead of the array i was working on but the database back end that i was (forced into) using does not support concatenation of strings in aggregation functions and that was critical for the report. So I had to mimic the effect in an array. in the end it was so inefficient that each time the report was run, I pulled a non aggregated recordset from the jet back end, inserted it into a temporary mysql table and then performed a simple aggregation query against the temp table. and built the report in a few lines of code. .

i had spent a day on the array, the recasting took less than half an hour. and i am sure that the code will have executed faster without all the conditionals that i was having to employ in the array transformation code i was messing with.

Sorry to ask but, in what way it would be more usable in comparison with the current method?

the comment was "idle" in that it was off the cuff gut-feel response. However i'm of the same opinion now that i have thought about it a bit more.

the schema i proposed appears more logically structured than yours as the logic that you were employing meant that there was always an element and only one element called subdir, basedir, filename in each tree limb. therefore it didn't seem necessary to me to give them numeric keys at that level. conversely you may have multiple SETS of those three items which meant (to me) that logic pointed towards adding a numeric identifier at the point in the tree above the sets.

once you have moved to this restructured tree the array is much easier to search
Code:
<?
$GLOBALS["site_pages"][] = array("basedir"=>"a", "subdir"=>"b", "filename"=>"c");
$GLOBALS["site_pages"][] = array("basedir"=>"d", "subdir"=>"e", "filename"=>"f");
$GLOBALS["site_pages"][] = array("basedir"=>"d", "subdir"=>"g", "filename"=>"h");
$tmp_array  = array();
foreach ($GLOBALS["site_pages"] as $key=>$testval):
	if (in_array("d",$testval)):
		$tmp_array[] = $key;
	endif;
endforeach;
print_r($tmp_array);
?>

this returns you an array of matching keys that you will look like this:
Code:
Array
(
    [0] => 1
    [1] => 2
)
then access the other variables in the tree like this
Code:
echo $GLOBALS['site_name'][$key[0]]["basedir"];
echo $GLOBALS['site_name'][$key[0]]["subdir"];
echo $GLOBALS['site_name'][$key[0]]["filename"];

this code will return all matches of the string. if you just want to return the first match then use array_search rather than in_array.

hth
Justin
 

Thanks guys.
Thanks a lot for those precious infos.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top