carlos1234 Posted October 29, 2009 Share Posted October 29, 2009 I have three associative arrays. $combinedSettings $userSettings $defaultSettings My function must combine the key and value from $userSettings and $defaultSettings into the $combinedSettings array. $userSettings will always contain more keys than $defaultSettings will ever have. So every once in a while there is an extra key and of course it's value in the $userSettings array than in the $defaultSettings array. If the value of a key in $userSettings is empty we then use the value for the same key in the $defaultSettings. Every key in $defaultSettings will always be present in $userSettings. $userSettings just adds a few extra keys and their values. Below is my working code but I am wondering if there is some way to make it more efficient, faster, perhaps with less code. It looks rather clutzy to me. Rather bloated. while (list($userKey, $userValue) = each($userSettings)) { while ($defaultKey = key($defaultSettings)) { $defaultValue = current($defaultSettings); if ($userKey === $defaultKey) { if ($userValue === "") { $combinedSettings[$defaultKey] = $defaultValue; } else { $combinedSettings[$userKey] = $userKey; } next($defaultSettings); // to allow key() to work properly above. } else { // add userSettings setting and value to combinedSettings and leave // defaultSettings where it is. $combinedSettings[$userKey] = $userValue; } break; } } Thanks. Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/ Share on other sites More sharing options...
Mark Baker Posted October 29, 2009 Share Posted October 29, 2009 doesn't array_merge() do what you want? Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947440 Share on other sites More sharing options...
carlos1234 Posted October 29, 2009 Author Share Posted October 29, 2009 array_merge() definitely does not do what I need Mark. It always takes the value of the second array when merging if the two keys are the same. For my needs $userSettings (the first array) always has precedence in the merge unless it is blank in which case I take the value in the same key in the $defaultSettings array. array_match() also appends new keys and their values to the end of the combined array which I do not want. I want keys to be inserted in their proper place in the order of keys. Thanks for the suggestion though. Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947445 Share on other sites More sharing options...
mpharo Posted October 29, 2009 Share Posted October 29, 2009 is using a database out of the question? a query would definatly simplify this... Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947448 Share on other sites More sharing options...
carlos1234 Posted October 30, 2009 Author Share Posted October 30, 2009 Yes...using a database is out of the question. I am developing a simplified web site creation system that involves reading a userSetting and defaultSetting ini files for it's settings. The system does not use the overhead of a database on purpose since it is meant to be lean and mean for the purpose of creating simple web sites like the kind that one needs to create for Adsense. Even if I stored the values of userSettings and defaultSettings in a database it would not alleviate me of having to figure out how to combine their values on the fly. Since my system accepts as input only one set of settings that are then used as the active settings to use. The code I posted works but I am just wondering if there is a more efficient way to do it. Actually I had to fix something in the code...the code below is what actually works as intended. while (list($userKey, $userValue) = each($userSettings)) { while ($defaultKey = key($defaultSettings)) { $defaultValue = current($defaultSettings); if ($userKey === $defaultKey) { if ($userValue === "") { $combinedSettings[$defaultKey] = $defaultValue; } else { $combinedSettings[$userKey] = $userValue; } next($defaultSettings); // to allow key() to work properly above. } else { // leave defaultSettings where it is but collect the right key/value into // combinedSettings array. if ($userValue === "") { $combinedSettings[$defaultKey] = $defaultValue; } else { $combinedSettings[$userKey] = $userValue; } } break; } } Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947498 Share on other sites More sharing options...
mikesta707 Posted October 30, 2009 Share Posted October 30, 2009 I would do it like so function combine($array1, $array2){//array1 has precedence $combined=array_merge($array2, $array1); //merge them all with array1 having precedence. //array merge will overwrite any default values, even if //the value is empty (ie "") //now go through, and replace any empty values with //their default values $keys = array_keys($array2); foreach($keys as $key){ if ($combined[$key] == "" || empty($combined[$key])){ //if we find a key in combined thats empty //replace it with default value $combined[$key] = $array2[$key]; }//end if }//end foreach }//end func Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947501 Share on other sites More sharing options...
carlos1234 Posted October 30, 2009 Author Share Posted October 30, 2009 Hmm...interesting solution you have there Mike. Very good! I will have to toy around with that some. Don't know if it's faster but then again my code operates fast enough so I am sure your solution will be more than adequate. It's certainly cleaner looking. The only "problem" which is really not a problem is that the keys will not be in the same order more or less as the order that they are found in inside the respective user and default setting files. But really the order of the keys in the arrays is only good for debugging. Once the code works flawlessly it won't matter what order the keys are in. Thanks for the tip! Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947503 Share on other sites More sharing options...
mikesta707 Posted October 30, 2009 Share Posted October 30, 2009 You could use array sort to put them in alphabetical order. As for faster or not, either one would only be slightly faster than the other. Unless you are processing GIGANTIC arrays, then you won't really see a difference. You could time it though, if you are curious. just do both 100 times, like $time = time(); for($i = 0; $i < 100; $i++){ yourMethod(); } echo "Us: ". (time() - $time) ."<br />"; $time = time(); for($i = 0; $i < 100; $i++){ myMethod(); } echo "and Them: ". (time() - $time) ."<br />"; edit: if you are processing huge arrays, I would just use databases. it would definitely be faster Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947514 Share on other sites More sharing options...
carlos1234 Posted October 30, 2009 Author Share Posted October 30, 2009 Thanks again Mike but my arrays won't ever be bigger than about 50 settings if that. So speed wise like you said...it won't make any bit of difference at least respecting anything that would be visible by the naked eye. I like your sorting idea except that my settings are grouped together and are not in alphabetical order in the ini files. But the internal ordering of the elements in the arrays that these settings are read into is only useful for me in debugging things. Once things are fully debugged the internal order of what is read into the arrays won't make any difference at all. Thanks again Mike. Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947515 Share on other sites More sharing options...
Zane Posted October 30, 2009 Share Posted October 30, 2009 I am wondering if there is some way to make it more efficient, faster, perhaps with less code. yes.. see below code. $userArray = array(); $defaultArray = array(); $combinedArray = array(); foreach($userArray as $k=>$v) if(empty($userArray[$k]) || is_null($userArray[$k])) $userArray[$k] = $defaultArray[$k]; nevermind above.. misunderstood. $userArray = array(); $defaultArray = array(); $combinedArray = array(); foreach($userArray as $k=>$v) { if(empty($userArray[$k]) || is_null($userArray[$k])) $combinedArray[$k] = $defaultArray[$k]; else $combinedArray[$k] = $userArray[$k]; } Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947585 Share on other sites More sharing options...
carlos1234 Posted October 30, 2009 Author Share Posted October 30, 2009 Thanks Zanus but it does not seem that your solution will do what I need. You see $k is not consistent as the right key between $userArray and $defaultArray as your solution supposes it is. $userArray has additional keys (with their corresponding values) more than $defaultArray. In other words every key in $defaultArray is also found in $userArray but $userArray has addtional keys not found in $defaultArray. What I originally had been trying to do was insert the extra keys from $userArray into $combinedArray just below the key in $defaultArray that it was related to. Let me give an example... $userArray keys and values: PageBackgroundImage= PageBackgroundImageUsed=yes ContentBackgroundImage=images/new-background.png ContentBackgroundImageUsed=no $defaultArray key and values: PageBackgroundImage=images/page-background.png ContentBackgroundImage=images/content-background.png What I would want to end up in $combinedArray would be: PageBackgroundImage=images/page-background.png PageBackgroundImageUsed=yes ContentBackgroundImage=images/new-background.png ContentBackgroundImageUsed=no Settings in $userArray take precedence over any settings in $defaultArray. Notice how the appropriate ....Used setting is inserted below the one that it applies to? That is what I originally had in mind and did with my code. I am going to flag this as solved for my purposes at this point since it does not seem that there is any really more efficient way to do this other than what has been proposed in the thread so far. Thanks again for the input you all. Much appreciated! Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947599 Share on other sites More sharing options...
Zane Posted October 30, 2009 Share Posted October 30, 2009 Thanks Zanus but it does not seem that your solution will do what I need. You see $k is not consistent as the right key between $userArray and $defaultArray as your solution supposes it is. How does this not do exactly that? $userArray = array(); $defaultArray = array(); $combinedArray = array(); $defaultArray['PageBackgroundImage'] = ''; $defaultArray['ContentBackgroundImage'] = 'default-content-image.jpg'; $userArray['PageBackgroundImage'] = ''; $userArray['ContentBackgroundImage'] = 'users-content-image.jpg'; $userArray['PageBackgroundImageUsed'] = 'yes'; $userArray['ContentBackgroundImageUsed'] = 'no'; echo "Defaults"; echo "", print_r($defaultArray), ""; echo "User-Defined"; echo "", print_r($userArray), ""; foreach($userArray as $k=>$v) { if(empty($userArray[$k]) || is_null($userArray[$k])) $combinedArray[$k] = $defaultArray[$k]; else $combinedArray[$k] = $userArray[$k]; } echo "Combined"; echo "", print_r($combinedArray), ""; ?> The Output: Defaults Array ( [PageBackgroundImage] => [ContentBackgroundImage] => default-content-image.jpg ) 1 User-Defined Array ( [PageBackgroundImage] => [ContentBackgroundImage] => users-content-image.jpg [PageBackgroundImageUsed] => yes [ContentBackgroundImageUsed] => no ) 1 Combined Array ( [PageBackgroundImage] => [ContentBackgroundImage] => users-content-image.jpg [PageBackgroundImageUsed] => yes [ContentBackgroundImageUsed] => no ) 1 EDIT: whooa... I hardly looked at that Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947643 Share on other sites More sharing options...
Zane Posted October 30, 2009 Share Posted October 30, 2009 Ah, I forgot to set the default PageBackground $userArray = array(); $defaultArray = array(); $combinedArray = array(); $defaultArray['PageBackgroundImage'] = 'default-image.jpg'; echo "Defaults"; [...] The Output: Defaults Array ( [PageBackgroundImage] => default-image.jpg [ContentBackgroundImage] => default-content-image.jpg ) 1 User-Defined Array ( [PageBackgroundImage] => [ContentBackgroundImage] => users-content-image.jpg [PageBackgroundImageUsed] => yes [ContentBackgroundImageUsed] => no ) 1 Combined Array ( [PageBackgroundImage] => default-image.jpg [ContentBackgroundImage] => users-content-image.jpg [PageBackgroundImageUsed] => yes [ContentBackgroundImageUsed] => no ) 1 Works like a charm for me Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947646 Share on other sites More sharing options...
carlos1234 Posted October 30, 2009 Author Share Posted October 30, 2009 Hmm....I'll have to take a second and closer look at your code Zanus. Maybe you came up with a solution that was so...well...elegant that it flew over my head . Thanks for going through the trouble of explaining your solution more. I will see about getting back to this later today. I have so much on my plate this morning that I just can't get to it right away. Carlos Quote Link to comment https://forums.phpfreaks.com/topic/179552-solved-is-there-a-more-efficient-way-to-code-this-than-what-i-have/#findComment-947889 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.