Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 3 of 3
  1. #1
    New Coder
    Join Date
    Jun 2006
    Posts
    67
    Thanks
    20
    Thanked 0 Times in 0 Posts

    Overwritten Array

    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]):
    Code:
    (
        [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:
    PHP Code:
    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!

  • #2
    Supreme Overlord Spookster's Avatar
    Join Date
    May 2002
    Location
    Marion, IA USA
    Posts
    6,278
    Thanks
    4
    Thanked 83 Times in 82 Posts
    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.
    Spookster
    CodingForums Supreme Overlord
    All Hail Spookster

  • #3
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,987
    Thanks
    4
    Thanked 2,660 Times in 2,629 Posts
    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.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •