...

View Full Version : Overwritten Array



coolcamo8642
01-10-2012, 08:44 PM
I'm working on a script that matches a list of allergies against a list of ingredients pulled from an external database. I've gotten it mostly working: it pulls in the data, explodes the list of ingredients, and properly matches a given ingredient. The problem is that it only matches the last ingredient in the user-given list, that is, if I enter 'salt' and 'sugar', it only shows matches for 'sugar' (or vice-versa) when both exist in the ingredient list.

Here's a sample list of ingredients after being exploded (this is stored in $foodArray[4]):


(
[0] => Array
(
[0] => water
[1] => chicken noodle soup
[2] => chicken stock
[3] => cooked enriched egg noodles
[4] => water
[5] => enriched wheat flour
[6] => wheat flour
[7] => niacin
[8] => ferrous sulfate
[9] => thiamine mononitrate
[10] => riboflavin
[11] => folic acid
[12] => eggs
[13] => water
[14] => cooked white chicken meat
[15] => carrots
[16] => celery
[17] => contains less than 2 % of the following ingredients
[18] => salt
[19] => modified food starch
[20] => onions
[21] => chicken fat
[22] => yeast extract
[23] => gelatin
[24] => chicken flavor
[25] => contains ascorbic acid
[26] => salt
[27] => sugar
[28] => disodium inosinate
[29] => disodium guanylate
[30] => soy protein concentrate
[31] => corn oil
[32] => dehydrated parsley
[33] => chicken flavor
[34] => contains chicken stock
[35] => chicken powder
[36] => chicken fat
[37] => oleoresin turmeric
[38] => flavoring
[39] => beta carotene for color
[40] => spice extract
[41] =>
)

)


There are instances of both salt and sugar in the above list, so the desired output is for it to show "Salt, Sugar". The following is code which matches ingredients (stored in $foodArray[4]) against allergies (stored in $allergyArray); it's inside of a loop which goes through each food item ($i), which contains a nested loop for each ingredient ($j), and another for each match ($k). I apologize for the sloppiness here - I'm no PHP expert and it was easier let it make the array deeper than figure out why it was doing it:


foreach($allergyArray as $allergy){

// Create Non-Quoted Var.
$rawAllergy = ucfirst(str_replace('\'', '', $allergy));

// Loop for Each Ingredient [$j]
for($j=0; $j < count($foodArray[4][$i]); $j++){

// Store Matched Ingredients in $foodArray[5]
preg_match_all($allergy, $foodArray[4][$i][$j], $foodArray[5][$i][$j]);

// Loop for Each Matched Allergy [$k]
for($k=0; $k < count($foodArray[5][$i][$j]); $k++){

// Check to See if a Match
if(empty($foodArray[5][$i][$j][$k][0]) == false){

// Check if Food Allergies Already Set
if(isset($foodArray[6][$i]) == false){
$foodArray[6][$i][$j] = ucfirst($foodArray[5][$i][$j][$k][0]);
}

// Condition for Duplicates
else if(in_array($rawAllergy, $foodArray[6][$i]) == false){
$foodArray[6][$i][$j] = ucfirst($foodArray[5][$i][$j][$k][0]);
}
}
}
}
}


In its current state, it will match allergies, but only the last one in the list. Any suggestions as to what I'm missing here would be much appreciated!

Spookster
01-10-2012, 09:00 PM
A few things to note here.

1. The use of variable names i,j,k,l, etc should really be avoided. They make code less readable than giving variables meaningful names. Variable names i-n are throwbacks from the days of Fortran where all integer variables had to start with the letters I-N. Modern day languages such as PHP here do not need to follow that archaic naming convention.

2. Avoid using "magic numbers" i.e. ($foodArray[5], $foodArray[6], etc). Using literals makes code much more difficult to read or follow. Instead constants should be defined and used in place of those literals. Makes it easier to read and update in case you use the same constants in numerous locations.

3. You mentioned all this data was from a database. Can you not just run a query on that database to match this data up? If you have this data in a database it seems senseless to try and manually manipulate relationships between the data after you have queried it from the database.

Fou-Lu
01-10-2012, 09:06 PM
I agree with spooks, in particular about putting the burden on the SQL when its possible to do so.
This: $foodArray[5][$i][$j][$k][0] kinda reeks to me of a normalization issue. If you have 5 levels of indirection for your array, something may not quite jive with your data.
To me, a structure of three tables: product, ingredient, productIngredient would be easy to implement a many to many. Tack on a fourth for allergen, and connect those to ingredientAllergen. Now you can search for either ingredients, allergens, or both at the same time, and find all corresponding ingredients and products. Best part is, you can do this from a single dimension for your output instead of 5 levels (which reminds me, where are you getting this from? The above array is only 1 level). If I see arrays > 3 dimensions, I pretty much immediately use objects just to keep it a little more flat.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum